# PGS Question



## jdawg (Aug 26, 2013)

On one page of script I have a dial sending 



> on ui_control($EFFECT)
> pgs_set_key_val(NOTE_EFFECT, 0, $EFFECT)
> end on



On the next page of script I have I have another dial 



> on ui_control($EFFECT_2)
> LOTSA OF THINGS HAPPENING
> end on
> 
> ...



Now the movement of the EFFECT dial on page 1, DOES move the EFFECT_2 dial on page 2, but it doesn't act the same as an "on ui_control" is there anyway to get it to act as such? Without having to declare all the same variables etc as on page 2? (there just isnt enough space to declare all these things on a singles page)

Thanking you


----------



## Big Bob (Aug 26, 2013)

There is no'software callback-trigger mechanism that allows you to trigger a ui callback from your script.

However, you can accomplish much the same thing by coding the body of the ui callback as a user function. Then you can *call* that function both from the ui callback and from wherever you want to 'software trigger' that callback.

Rejoice,

Bob


----------



## jdawg (Aug 26, 2013)

Thanks BOB, 
do you have an example of what you mentioned? Im really struggling here, I wish it could all go in the same page, but theres so many lines now I just get PARSE ERRORS in kontakt and it wont let me compile. So I need to try split amongst the pages. 


Thanking you


----------



## Big Bob (Aug 26, 2013)

*on init*
``*declare* ui_switch DoStuff
``message('')
*end* on

*on ui_control*(DoStuff)
``*call* DoLotsOfStuff
*end* on

*function* DoLotsOfStuff
``DoStuff := 0
``message('Doing lots of stuff') 
``wait(1000000)
``message('') 
*end* *function*

*on controller*
``*if* CC_NUM = 1
````*call* DoLotsOfStuff
``*end* *if*
*end* on


The callback handler for the switch is executed whenever you click on the switch but is also executed whenever you move the mod wheel. So the CC callback is essentially triggering the switch callback.

Does this make it any clearer?

Rejoice,

Bob


----------



## jdawg (Aug 26, 2013)

oo that seems really useful, but im not sure how it will make the pgs thing easier : (

my issue there is, if i have everything in the same script, im literally declaring so many things, that I get a parse error half way through, so i need to split the script accorss 2 slots. 

1 slot for the visual GUI, and the second slot to handle all the background stuff, in this case handling tuning scales. (change pitch ) stuff on a per note basis. as well as other things. 

I had hoped I could have the control in slot 1 affect the control in slot 2, but it doesnt work unless it can call back all its on ui control functions. Do these functions work accross scripts? 

Could I for instance, on pgs ping up the call ?



> on ui_control($EFFECT_2)
> LOTSA OF THINGS HAPPENING
> end on
> 
> ...




would be interesting if that worked


----------



## Big Bob (Aug 26, 2013)

I'm not sure I have a clear picture of what you are trying to accomplish.

Are you saying that you have a knob and related callback in slot 1 and then you want to put another copy of that knob on your slot 2 panel?

Then, you want it to work so that when either knob is turned (ie on panel 1 or panel 2) that the other knob (along with all the stuff controlled by the knob) will follow suit?

If so, is the stuff you are doing to parameters and such performed in the slot 1 callback for knob 1? Could you post a greatly simplified example of what your callback for knob 1 looks like now?

As to global user functions, there may be a way to sythesize them. I haven't thought about this for some time but I used to do that sort of thing back in the K2 days (this was before NI added user functions and the pgs system).

I should also mention that the 'parse error' problem has also been with us for many years now. There are a few tricks that you can use that will sometimes enable you to fool the compiler into accepting longer ICBs. One thing you can try is to enclose blocks of ICB definitions in if-else bodies.

For example:


```
on init
  if 1 = 1
    blah
    blah
    blah
  end if
  if 1 = 1
    blah
    blah
    blah
  end if
  if 1 = 1
    blah
    blah
    blah
  end if
end on
```

The compiler may work on each block and simplify before moving on to the next block. I've forgotten a lot of the details but this is the general idea.

Rejoice,

Bob


----------



## mk282 (Aug 26, 2013)

jdawg @ 26.8.2013 said:


> my issue there is, if i have everything in the same script, im literally declaring so many things, that I get a parse error half way through, so i need to split the script accorss 2 slots.



Well that sounds wrong. Define "declaring so many things". How many?


----------



## jdawg (Aug 26, 2013)

Oh wow, I didnt realise it was an issue with kontakt, I will try that trick : ) FINGERS CROSSED. thanks for the tip : )


----------



## Big Bob (Aug 26, 2013)

If you like I can give you an example of how you could implement an inter-script pair of ganged knobs using the pgs system (since that may be what you were shooting for). This could be arranged to put the bulk of the algorithmic code in only one of the two scripts without having to replicate the code in the other script slot.

However, Rosie just called me for lunch so I'll check back afterward to see if it seems appropriate to post such an example.

Rejoice,

Bob


----------



## Big Bob (Aug 26, 2013)

OK, I'm back from lunch. I guess you may be sound asleep by now :lol: 

However, just in case this is the sort of thing you were wrestling with, here's an example of how you could have a 'clone' knob in script slot 2 that will perform all the actions as its counterpart knob in script slot 1.

_{ Script Slot #1 }_

*on init*
``pgs_create_key(KNOB_MASTER,1)
``*declare* ui_knob Knob1 (0,1000000,1)
````read_persistent_var(Knob1)
````pgs_set_key_val(KNOB_MASTER,0,Knob1) 
``make_persistent(Knob1)
*end* on

*on pgs_changed*
``Knob1 := pgs_get_key_val(KNOB_MASTER,0)
``*call* lots_of_stuff
*end* on

*on ui_control*(Knob1)
``pgs_set_key_val(KNOB_MASTER,0,Knob1)``
*end* on

*function* lots_of_stuff
``_{ but no wait statements }_
``message(Knob1)
*end* *function*


_{ Script Slot #2 }_

*on init*
``*declare* ui_knob Knob1x (0,1000000,1)
*end* on

*on pgs_changed*
``Knob1x := pgs_get_key_val(KNOB_MASTER,0)
*end* on

*on ui_control*(Knob1x)
``pgs_set_key_val(KNOB_MASTER,0,Knob1x)
*end* on

You can name the clone knob in slot 2 with the same name as you use in slot 1 if you wish since each script slot has its own namespace (except for pgs vars of course).

If your complex 'lots_of_stuff' rountine uses wait statements, let me know and I can discuss how to handle that.

Rejoice,

Bob


----------



## mk282 (Aug 27, 2013)

Big Bob @ 26.8.2013 said:


> *function* lots_of_stuff
> ``_{ but no wait statements }_



And no purge_group() or allow/disallow_group(), sadly...


----------



## jdawg (Aug 29, 2013)

Not going to lie, been having so much fun with these function calls, 

is there anyway to have the function callback trigger on init ?

Would be super amazing at this point.


----------



## Big Bob (Aug 29, 2013)

There is no way I know to restart the script from within the script if that's what you are asking. You'll have to hit the Apply button or reload the script as an nkp or reload the instrument containing the script, etc.

Rejoice,

Bob


----------



## jdawg (Aug 29, 2013)

Oh I think I was meaning the opposite, 

If after my 

ON INIT

END ON

I have 

function DO THINGS
things being done
end function

How can I call DO THINGS, so that it calls when you open the patch, and not when you press a button, 

If I put call DO THINGS before Ive written the function it comes up as an error as its not been delcared yet etc etc


----------



## mk282 (Aug 29, 2013)

Function has to be declared before it can be used.

If you want to call a function after initialization, you need to do it either via PGS or via listener callback (I do it via PGS).

So something like:


```
on init
    <stuff>
    pgs_create_key(INIT,1)
    pgs_set_key_val(INIT,0,1)
end on

function Stuff()
    <more stuff>
end function

on pgs_changed
    if (pgs_key_exists(INIT) and pgs_get_key_val(INIT,0) = 1)
        call Stuff()
        pgs_set_key_val(INIT,0,0)
    end if
end on
```


Also you didn't quite reply on my question in my second preceding post


----------



## jdawg (Aug 29, 2013)

Oh sorry, 
I think im declaring around 300 things. Mainly due to lack of knowledge probably not knowing how to void this by setting up an array. But I would have though it could have handled it.


----------



## argitoth (Aug 29, 2013)

What about declaring arrays rather than individual variables? Will that help lessen declarations and therefore allow you to have a script in one slot?


----------



## mk282 (Aug 29, 2013)

jdawg @ 29.8.2013 said:


> Oh sorry,
> I think im declaring around 300 things. Mainly due to lack of knowledge probably not knowing how to void this by setting up an array. But I would have though it could have handled it.



I suspect they are not all of same control type? Because maximum limit (since Kontakt 4.2) is 256 controls of each UI control type (knob, slider, switch...), so if you had 257 ui_sliders declared, it would throw an error.


----------

