1. IMPORTANT:
    We launched a new online community and this space is now closed. This community will be available as a read-only resources until further notice.
    JOIN US HERE

Does a change to one PGS var in script A mean all PGS vars "changed" in script B?

Discussion in 'Scripting Workshop' started by cbmtrx, Dec 12, 2017.

  1. cbmtrx

    cbmtrx NI Product Owner

    Messages:
    226
    I have a couple of different PGS vars being triggered independently in one script and was curious whether the other script would simply run everything in on pgs_changed regardless of which PGS key had been modified.

    Is there any mechanism within the pgs_changed call to check which PGS var was changed? Just an effort to cut down on redundant functions being triggered every time...
     
  2. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    Yes, PGS callback gets executed on every set_pgs_key_val() command call, in all script slots. So, if you're not careful about things, you can do a lot of value assignments or function calls that aren't always necessary.

    There's no mechanism to check which PGS key was changed, but you can insert semaphore variables that prevent doing excessive tasks. This is the way to do it.


    Let's say you have a variable $var, which you want to use in one of your script slots so that it picks up a value from a certain PGS key (doesn't matter which). Then:

    Code:
    on pgs_changed
        if pgs_key_exists(MY_PGS_KEY) and pgs_get_key_val(MY_PGS_KEY, 0) # $var
            $var := pgs_get_key_val(MY_PGS_KEY, 0)
        end if
    end on

    This will ONLY change the value of $var, if the PGS key value is actually different from what's already stored in $var. Rinse and repeat for every variable you have linked this way via PGS.
     
  3. cbmtrx

    cbmtrx NI Product Owner

    Messages:
    226
    Huh. I assume it's OK to put a while loop (or anything) inside that if statement?
    Code:
    on pgs_changed
        if pgs_key_exists(MY_PGS_KEY) and pgs_get_key_val(MY_PGS_KEY, 0) # %var[3]
    
            $i := 0
    
            while ($i < 10)
                %var[$i] := pgs_get_key_val(MY_PGS_KEY, $i)
                inc($i)
            end while
    
        end if
    
    end on
    
     
  4. EvilDragon

    EvilDragon Well-Known Member

    Messages:
    19,938
    Yeah whatever you want to do, but check should be done first. So you don't do EXCESSIVE loops whenever an unrelated PGS key gets changed.
     
  5. cbmtrx

    cbmtrx NI Product Owner

    Messages:
    226
    Pretty nifty, thanks.
     
  6. cbmtrx

    cbmtrx NI Product Owner

    Messages:
    226
    An added wrinkle to this: I have one control in each script that affects the same source. When I use a PGS var to update the other knob, it works but when I have separate PGS vars doing the same for both knobs in both scripts it obviously sets up a feedback loop and nothing changes.

    I thought about having an array in just one of the scripts to save the incoming PGS var change, then have that "reset" its control knob to that value. But then I have the problem of how to tell it to update... A timer seems kludgey. It doesn't even have to be instantaneous because this script is hidden while the user is on the other script controlling the knob.

    Any suggestions?
     
  7. Reid115

    Reid115 NI Product Owner

    Messages:
    40
    Is this still true? The manual says the same thing but my testing suggests otherwise. For example, place this script in slot 1:
    Code:
    on init
        declare $pgs_foo := -1
        declare $pgs_bar := -1
        declare $pgs_hello := -1
        declare $count := 0
    end on
    
    on pgs_changed
        wait(1)
        inc($count)
        $pgs_foo := pgs_get_key_val(FOO, 0)
        $pgs_bar := pgs_get_key_val(BAR, 0)
        $pgs_hello := pgs_get_key_val(HELLO, 0)
        message($count & ": " & $pgs_foo & ", " & $pgs_bar & ", " & $pgs_hello)
    end on
    And this script in slot 2:
    Code:
    on init
        declare $foo := 5
        declare $bar := 8
        declare $hello := 12
        pgs_create_key(FOO, 1)
        pgs_create_key(BAR, 1)
        pgs_create_key(HELLO, 1)
    end on
    
    function something1
        pgs_set_key_val(FOO, 0, $foo)
        pgs_set_key_val(BAR, 0, $bar)
    end function
    
    function something2
        pgs_set_key_val(HELLO, 0, $hello)
    end function
    
    on persistence_changed
        call something1
        call something2
    end on
    If every pgs_set_key_val() in slot 2 calls pgs_changed in slot 1, then $count should be 3 after startup/hitting panic button and you should see the message "3: 5, 8, 12". However, it prints out "1: 5, 8, 12", suggesting that pgs_changed was only called once. Is there some sort of consolidation going on behind the scenes? Other testing suggests that it's always the final pgs_set_key_val() call that finally triggers the callback.