Home AMX User Forum NetLinx Studio

PERSISTENT Variables in Modules

Greetings,

It seems that variables defined as PERSISTENT in modules do not retain their value after an upload with no code changes to the variables between uploads.

Is this normal?

Must PERSISTENT variables be defines in the master program??

Comments

  • TurnipTruckTurnipTruck Posts: 1,485
    Would an INCLUDE file be more appropriate for something that relies on PERSISTENT variables?
  • viningvining Posts: 4,368
    Read technote: 480.

    Recent thread of persistance in structures which evolved to be a module issue!
    http://amxforums.com/showthread.php?t=2130

    You can find work arounds in the above thread.

    in short modules do not support persistent variables. Well let me expand that, you can not create and declare a variable persistent w/ in a module but you may pass it persistent variables.

    Read through the thread and the technote and you'll have a better understanding!
  • TurnipTruckTurnipTruck Posts: 1,485
    Thanks for that.

    Being new to modules, one of my main goals in using them is to get as much fluff out of my Master program as possible and put it in the modules.

    That being said, I'll have to leave the persistent variables in the M file instead and pass them in to the module. That is what I have done, and working fine.

    Thanks again!
  • viningvining Posts: 4,368
    To clear up your main use of include files is fine.

    Quite frankly I don't know of any real benefits to using modules other than keeping personal programs from being used by others should a system be taken over by some other company.

    Other than that modules offer only negative aspects and obstacles.

    With me it's an ego thing, the ability to overcome an obstacle such as creating modules. Otherwise why bother. It's all about the challenge and underlying ego! Having said that, overcoming challenges and obstacles leads to growth in both knowledge and unfortunately ego which perpetuates this viscous cylce. Such is life!
  • TurnipTruckTurnipTruck Posts: 1,485
    How do INCLUDEs behave in terms of device and variable definitions?

    If I device is defined in the main program, can it be refered to in the include with doing anything to bring it in?
  • vining wrote:
    Quite frankly I don't know of any real benefits to using modules

    Modules achieve many very useful goals, like code reuse, detail hiding and abstraction, although most of them can be achieved with includes if you really want to (and had to in Axcent boxes.)

    The biggie is multiple instantiation.

    My current project has the control module instantiated 4 times: for the Jury Court, the District Court, the Conference Room, etc; and the camera module twice per court; and the Plasma module twice for one court; etc.

    Driving two devices with one piece of code is possible (but nasty) using arrays; using modules it is completely frictionless.

    And note that you could build a huge module and compile in 100 instances and only one copy of the code would be downloaded to the controller; the compile size only gets bigger to allow for variables (or something like that.)
  • viningvining Posts: 4,368
    Oh yeah! I forgot about instances. That's true, that is a huge benefit of modules although in my projects it isn't usually required but in bigger jobs, very important.

    In effect an include file is functional part of your main program as the system gets compile the includes are "included" or pulled into the main and effectively creates one big main, incorporating all the includes. Variables and constants are all shared between all includes and the main because they are in effect one file, however sometimes you must watch the order of includes so that in the order of compiling an earlier include doesn't reference a varaible or constant in a later one because at compile time when the earlier include gets pulled in it can't see the other stuff that the late include contains because it hasn't been included yet. I think that's mainly a flaw in the compiler, where it should make mutliple passes through the main and includes. The first pass to essential build the entire file or main and then the second to compile, then the order of includes wouldn't matter.

    NMarkRoberts is right, modules are beneficial but includes are equally as useful unless instances are required or a need to protect itellectual property is important. They are both equally as portable and reusable.
  • DHawthorneDHawthorne Posts: 4,584
    Greetings,

    It seems that variables defined as PERSISTENT in modules do not retain their value after an upload with no code changes to the variables between uploads.

    Is this normal?

    Must PERSISTENT variables be defines in the master program??

    Modules do not support the PERSISTENT keyword internally, period. The only way to have PERSISTENT variables within the module is to declare them in the calling program and pass them to the module as an argument. If you don't have a lot of them (and you shouldn't really, you can eat up your memory fast if you overuse persistence), this is not much of a limitation.

    I would choose a module over an include in almost every case:

    1) Instancing; you can have one piece of code running multiple devices
    2) Re-use; just add the module to your main code. Once written, you can use it every time you need that same device. If you update it, it gets updated on all future uses (and retro's to the old ones if you didn't just copy it). It could be argued that includes are also re-usable, and that is correct, but I find modules a more graceful way to do it. For example, if I had a system that was running multiple theaters, each could use the identical code as full-blown theater modules running as multiple instances. You would be hard pressed to do this with includes, and the collisions would be a nightmare to sort out.
    3) Includes gum up debugging; the NetLinx compiler really doesn't like includes very much - it get line numbers wrong on error messages.
    4) Variable scope; you have to be careful about variable names in includes not to duplicate them. In a module, you can re-use the same variable names, and don't have to worry about them.
    5) Protecting proprietary code; you can only put the compiled module in a project file and so protect your code from other programmers or clients that think they can muss with things. It gives you better control over your device code, and you know there haven't been unauthorized, or even legit changes that someone forgot to tell you about.
  • TurnipTruckTurnipTruck Posts: 1,485
    Thanks Dave,

    So if I want to write a module which manages something with presets, where would the declaration of the persistent variables typically be placed?

    Must the module be packaged with an include for variable declarations??
  • Joe HebertJoe Hebert Posts: 2,159
    DHawthorne wrote:
    I would choose a module over an include in almost every case:
    Same here. I would add TIMELINE IDs to the list also. I had an INCLUDE once that mistakenly used the same TIMELINE ID as another INCLUDE. It took me a bit to figure out why my program wasn?t working correctly. Like variables and constants, TIMELINE IDs (another constant) maintain scope within the module only.
    DHawthorne wrote:
    Includes gum up debugging; the NetLinx compiler really doesn't like includes very much - it get line numbers wrong on error messages.
    Modules are even worse. It?s damn confusing trying to set breakpoints and step thru code because it?s always one line off.. The debugger steps on blank lines, comments ? a real pain in the butt. But I?d still take a module over an INCLUDE if push came to shove.

    Modules (even with their shortcomings as mentioned in previous threads) make for more object oriented code and I feel it took AMX to a new level. I know it?s not standard practice but I?ll combine Comm and GUI in the same module sometimes. Drop in a module and you?re off and running.

    I like iNCLUDEs also (and use them a lot) but for me it?s more for separating and organizing code. You can re-use code from an INCLUDE as long as you?re careful with variable names, constants, and such.
  • DHawthorneDHawthorne Posts: 4,584
    Thanks Dave,

    So if I want to write a module which manages something with presets, where would the declaration of the persistent variables typically be placed?

    Must the module be packaged with an include for variable declarations??

    You have to declare your persistent variables in the main program, and pass them along to the module as parameters. I do it all the time for exactly the scenario you mention - presets.

    Something like this:
    DEFINE_VARIABLE
    
    PERSISTENT CHAR sPresetNames[100][30]
    PERSISTENT CHAR sPresetValues[100][10]
    
    DEFINE_MODULE 'Example preset Module' PRESET1 (dvTuner, sPresetNames, sPresetValues)
    
  • Spire_JeffSpire_Jeff Posts: 1,917
    Thanks Dave,

    So if I want to write a module which manages something with presets, where would the declaration of the persistent variables typically be placed?

    Must the module be packaged with an include for variable declarations??

    You have to define the persistent variables in your main program and then pass them to the module. I have moved away from persistent variables for things like presets because when I do have to change the program, the client has to reset all of their presets (or more likely, I had to look at them and then re-enter them). I have been using the VARIABLE_TO_XML and VARIABLE_TO_STRING funtions and saving them info to a file. On a reboot, the module reads the file back and repopulates the variables. This allows me to move the preset between processors and send a backup via email easily.

    Jeff

    P.S.
    I do use persistent variables for VERY simple variables like say a prefered heat and cool temps or passwords.
  • viningvining Posts: 4,368
    Joe wrote:
    Same here. I would add TIMELINE IDs to the list also. I had an INCLUDE once that mistakenly used the same TIMELINE ID as another INCLUDE. It took me a bit to figure out why my program wasn?t working correctly. Like variables and constants, TIMELINE IDs (another constant) maintain scope within the module only.

    Kinda off on a tangent but when ever use TIME_LINE ID's I alway copy them and place them in my main in a specific section in DEFINE_CONSTANT and then simply comment them out leaving the working ID in the include. So I always have a complete list of the ID's and what numbers have been used.

    With variable & constants I always try to make the name device specific like nVST_var or VST_MAX_STR_LENGTH for example. VST would be for viewstats.

    I wasn't sure about the scope of modules though, that's nice to know.
  • Modules - the only way to fly

    Now that various folk (including me) have given their reasons why they prefer modules over other approaches, the best reason so far being their "gracefulness" 8^), let me summarise, and I shall paraphrase Norm:

    "Modules. You Can't Live Without 'Em... Pass the beernuts?"

    Feel free to Google the last phrase if the reference is obscure.
Sign In or Register to comment.