# Merging multiple "While" statements



## Raptor4 (Aug 31, 2012)

Hi KSPs,
I wanna use a few "While" conditions with multiple continuous operations in between.
Let's say you run two objects simultaneously:
While object 1 is running from point A to its point B destination then when reach the B destination its "while" statement to be terminated - i.e it stops on point B.
While object 2 is running from point A to its point B destination (which B is different from object 1 B one) then when reach the B destination the "while" statement to be terminated etc.
If I use separate "while" and "end while" for each object condition then the final operation is serial i.e objects do not run simultaneously.
I tried to merge the "While" statements to two ones only (while & end while) and use some flag and "if" conditions inside but the termination is not separate for each object.
Any clues... :? 
Regards


----------



## Big Bob (Aug 31, 2012)

Hi Ivan,

For the two while loops to run concurrently, they will have to be executed as two separate threads/tasks. With the KSP this is only possible if the while loops each contain at least one wait statement in the loop. This is because the KSP runs essentially as a non-pre-emptive multi-tasking model.

Do your loops contain waits? If so, in what callback are you wanting to run these concurrent loops? Armed with these answers, I might be able to suggest how you could go about this.

Rejoice,

Bob


----------



## Raptor4 (Aug 31, 2012)

Hi Robert,
Thanks for the immediate input!


> Do your loops contain waits?


Yes.


> If so, in what callback are you wanting to run these concurrent loops?


On ui_control CB in my current project which will control other UIs but I just created a simple demo using UI CB which controls note events.

```
on init
  message("")
  declare $i
  declare $i2
  declare ui_switch $Run
end on

on ui_control($Run)
  $Run := 0
  $i := 60
  $i2 := 67
  while ($i<73)
    play_note($i,120,0,$DURATION_QUARTER)
    inc($i)
    wait(500000)
  end while

  while ($i2<80)
    play_note($i2,80,0,$DURATION_QUARTER)
    inc($i2)
    wait(500000)
  end while
end on
```
As you see in the demo both loops will run "in serial" while I what them "in parallel".
Keep in mind that I need different boolean conditions for each loop. Let's start with two loops running in parallel using different conditions...
Thanks in advance !
R4


----------



## Big Bob (Aug 31, 2012)

OK. I can show you how to do what you want but right at the moment, I'm overloaded. But, I will get back to you ASAP. Hang in there! :lol: 

Rejoice,

Bob


----------



## Big Bob (Aug 31, 2012)

OK Ivan,

Maybe this will get you started.

*on init* 
``message('') 
``*declare* i
``*declare* i2
``*declare* ui_switch Run 
``*declare* task2_id
*end* on 

*on ui_control*(Run) 
``Run := 0 
``i := 60 
``i2 := 67 
``task2_id := play_note(0,1,0,1)
``*while* (i < 73) 
````play_note(i,120,0,DURATION_QUARTER) 
````inc(i) 
````wait(500000) 
``*end while* 
*end* on

*on release*
``*if* EVENT_ID = task2_id
````*while* (i2 < 80) 
``````play_note(i2,80,0,DURATION_QUARTER) 
``````inc(i2) 
``````wait(500000) 
````*end while*`````
``*end* *if*
*end* on

The basic idea here is to start a background process in the RCB by using the old blip note zero trick. I'm sure you will figure it out. 8) 

This example is perhaps a little oversimplified but it will work for the specific task at hand. However, once you start executing concurrent processes you have to watch out for all kinds of subtle issues that can bite you. For example you can't use shared variables and in your case, polyvars won't help because they can't be used in a UI callback.

Are you familiar with the Task Control Module (TCM) that Nils and I added to the KSE a while back? If not, you should probably download the pdf User's Guide (from Nils' site) because it has a lot of pertinent info on multi-tasking and thread-safe variables and such.

Rejoice,

Bob

*EDIT: I should probably also mention that the simplified example above will not properly handle the situation if you activate the ui callback again while the loops are still running. This 're-entrance' situation can be handled also but it requires additional coding techniques. Task re-entrance is also discussed in the TCM guide.*


----------



## Raptor4 (Sep 2, 2012)

Hi Robert,
I'm sorry for the short latency - I was away from Internet for a while and there is at least 10hours time difference between us which is another problem regarding day/night...
What I say - it is BRILLIANT trick ! I got it immediately cause the previous day I tried lots of techniques and just missed that variant. I'm used to do such "dummy" messages combined with some schemes but it was in my Logic Environment models - I have not thing to do that in the KSP...
Regarding your 're-entrance' edit. Just to say - I use an array for the "tasks" and very precise conditions. I just tested that with three loops and they work perfect. I have a "Time" control UI so I slowed down the time to be able to run the CB again during the loops operation. 
Regarding TCM - I knew it but not quite familiar with that yet. I download the PDF as you recommended and will learn it when have time. By the way I have to execute about 28 loop tasks at a time so I will bring the prototype into the real project and try - will keep you in touch what's going on.
Thanks again mate !

God bless you !

Ivan


----------



## Lindon (Sep 3, 2012)

Just for fun there are at least two other ways to do this....

1. Use one while loop with a smaller wait statement. For instance I have a loop running for each step in MATRIX (check the demo video here: http://www.youtube.com/watch?v=lBdCmXG_FI4&feature=plcp), but several notes play in each iteration of the loop - no problem, but some of those notes are "repeaters" (they play more than one note...) So I divided my loops wait statement by 12 (I can have 2,3 or 4 repeating notes) and in iteration 1 of the loop play all "std" notes" and in iterations 1 and 6 play notes that play twice, in iterations 1,5 & 9 play all notes repeating 3 times, and in iterations 1,4,7 & 10 play those notes repeating 4 times...

Thus I have a while loop that is executing up to 4 different "streams" of activity each stream running on its own internal clock... 

2. Use a downstream script. The last GRID MACHINE instrument (RIVER sorry not out yet so no video..) has 8 streams of activity...each stream plays up to 3 notes of arbitrary length and arbitrary space between each note...in then end too hard for the approach above. So I just put the note playing info. in a message to pass down to a "play engine" which, given everyone has a wait statement (as Bob points out) means an on <event> gets triggered for each of my messages...in the downstream script and Kontakt handles the (apparent) concurrency for me...

Hope this helps - might not be the best explanation in the world I havent had any coffee yet...


----------

