Author Topic: How are variables handled in .NET and is it relatable to LISP?  (Read 268 times)

0 Members and 1 Guest are viewing this topic.

Rustabout

  • Newt
  • Posts: 113
In AutoLISP it's quite simple:

(defun <function name> ( <arguments> / <local variables> )

... and anything declared within the function itself is a "persistent" or "global" variable, from an AutoLISP programmer's perspective.

I'm looking for a way to both set global variables within a drawing (that will persist from session to session) and variables that will be retained for that session but disappear when closing the drawing.

I'm sure this is quite easy to achieve in .NET but I have had any luck searching for the answer as of yet.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7277
  • AKA Daniel
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #1 on: May 01, 2022, 01:32:38 AM »
Not sure if itís in .NET, but from ARX one might use functions AcedPutSym, AcedGetSym and AcedEvaluateLISP (COM EvalLispExpression)

You do know .net and lisp can communicate with each other, right? You can create a .NET function excepts and returns variables to lisp.
An Idea is to create a .NET function that returns a list of variables back to lisp. Search for the LispFunction attribute

cheers : )
 
Retired

kdub

  • Mesozoic keyThumper
  • SuperMod
  • Swamp Rat
  • Posts: 1438
  • class keyThumper<T>:ILazy<T>
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #2 on: May 01, 2022, 02:58:43 AM »
I assume these would do the job ??

public object GetLispSymbol(string name);
Declaring Type: Autodesk.AutoCAD.ApplicationServices.Document
Assembly: accoremgd, Version=24.2.0.0


and

public void SetLispSymbol(string name, object value);
Declaring Type: Autodesk.AutoCAD.ApplicationServices.Document
Assembly: accoremgd, Version=24.2.0.0

added
At least we no longer need to jump through the Pinvoke hoops like 10 years ago  :)
http://www.theswamp.org/index.php?topic=35714.0
« Last Edit: May 01, 2022, 03:08:07 AM by kdub »
called Kerry in my other life

Sometimes the question is more important than the answer.

I don't really work crazy hours . . I just live at UTC + 12.00
#ridesober

gile

  • Water Moccasin
  • Posts: 2379
  • Marseille, France
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #3 on: May 01, 2022, 03:03:49 AM »
Hi,

AFAIK, LISP variables are never "persistent".
Local variables only exist within the function they're declared in; global variables exist for all LISP functions during the session.
This is called the 'scope' of a variable. With .NET (C#), the scope of a variable is limited by the curly brackets the variable is declared in.
If the variable is declared within a method, its scope is limited to this method, it's a 'local variable'.
If the 'variable' is declared within a class (or structure), it is called a field, its scope depends on its 'access modifier':
- private (default): the scope is limited to the class
- protected: the scope islimited to the class and all derived classes
- internal: the scope is limited to the project
- public: all classes can access the field
(using properties instead of internal or public fields is a better prctice to respect encapsulation).

In both environments, drawing persistent data have to be written in xdata or xrecords.
Speaking English as a French Frog

Rustabout

  • Newt
  • Posts: 113
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #4 on: May 01, 2022, 10:35:43 AM »
Thanks for all the extremely helpful info!

It's Alive: I am aware they communicate and gradually exploring that. I was super excited when I created my own LISP function and it turned blue when I typed it's symbol in VLIDE; man was that ever cool!! I'm only just scratching the surface of what's available. At the same time I'm progressing so fast at .NET that I can almost just write my old LISP routines in .NET faster than re-wiring stuff.

kdub: Those will be extremely helpful!

gile: I misused the term "persistent". In AutoLISP you can get away with very little "mainstream" knowledge, so many of the terms I used are incorrect. I guess I meant that I wanted the variables to exist in their state for the duration of the session. I'll describe in detail me situation: I'm making an improved version of a LISP routine that draws stairs based on user input. It collects various inputs including total height, number of risers, and a few other parameters. My intent is/was that if the command is run again within the same session, I want all the previous inputs to fill the form (I'm using a WinForm). The .NET wizard template's notes mention that the main enclosing class is instantiated when the command is run for the first time within that session; I wondered if having my variables declared within that class itself (they are currently in the form's cs file... which triggered a light bulb as I'm typing...) is key. Since that class will be instantiated for the remainder of the session, it's variables will exist for the remainder as well?

Here's AfraLISP's tutorial on how to store variables with AutoLISP:
https://www.afralisp.net/autolisp/tutorials/application-data.php

It's much simpler than using xData/xRecords. I suppose it's kind of the same? It only allows one to store strings, but easy conversions along with the simplicity of most AutoLISP programs means it doesn't affect much.

I've used xData only to store information in an object itself (lines and blocks). In that application I created a way to have "Revit" style tags. Mine worked better than Revit's actually :-O . The code was quite intensive (for me at least) especially compared to the setcfg/getcfg pathway demonstrated in the link above.



gile

  • Water Moccasin
  • Posts: 2379
  • Marseille, France
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #5 on: May 01, 2022, 11:11:26 AM »
You probably can get some inspiration from the examples of this topic. It shows, among other things, how tu use default values (instance fields of the main class) in a dialog defined in another class.
Speaking English as a French Frog

Rustabout

  • Newt
  • Posts: 113
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #6 on: May 01, 2022, 03:33:39 PM »
I *think* I get it. Your link/site was very helpful.

From your site:

    public class Commands
    {
        // instance fields
        Document doc;  // active document
        double radius; // radius default value
        string layer;  // layer default value


  ... so when the command is used for the first time within the session, the "Commands" constructor runs (in this case you've explicitly created your own constructor in order to load default values). The "Commands" class object will remain instantiated throughout the session (it doesn't "deconstruct" after the command finishes), meaning any variable changes will also remain throughout the session. So during the first call, or subsequent calls, if the user changed the "radius" to 12.0 it would retain that value (for that session).

I've been doing some pretty crazy stuff including placing my variables in the code behind (which I know is a no-no but very tempting for beginners). I've actually almost got everything working, but going back in and coding everything properly will be a good exercise I think.

Thanks so much for your help. I've gotten usefulness far beyond my original question!! :-) . Very excited to try it out (but less excited to fix my code hehe)

n.yuan

  • Bull Frog
  • Posts: 327
Re: How are variables handled in .NET and is it relatable to LISP?
« Reply #7 on: May 02, 2022, 09:50:07 AM »
When a CommandMethod (a command) is call the first time in an Acad session, the CommandClass is instantiated by AutoCAD. You need to understand the difference of CommandMethod being static or non static: when the CommandMethod is static, a single CommandClass instance is created at session level, while if the CommandMethod is not static, a CommandClass instance is create at each Document level where the command is called. Yet, you never need to "new" a CommandClass: AutoCAD does it for you, when CommandMethod is called. In general, one does not create a constructor for a CommandClass.