Structuring a timer (with clones!)

Sorry, I honestly feel bad asking so many questions here. Such a noob with this!

I have a looper control that I'm cloning several times.
Within this looper, I want to have a timer that first turns the control grey, then stops the loop. What I've made so far works ... most of the time. But I'm getting weird behaviour which I suspect might be because of the way I'm using vars to simplify syntax within the timers and clones. A few questions -

  1. Is there a danger that vars within clones will clash?
  2. Is there a better way to structure these if statements?
  3. how can I cancel the setInterval timer from outside the timer? (Like from the 'erase' button)
if (value == 1) {

  // Set time fader to 0
  set(getProp("parent", "id") +"Timer", 0)
  
  // Make GoGrey variable x seconds less than MaxTime
  var GoGrey = (get("MaxTime")-60)
  
  // LOOP TIMER
  setInterval(function(){
    
    // Simplify syntax
    var parent = getProp("parent", "id")
    var CurrentTime = get(parent + "Timer")
    
    // Increment Timer fader
    set (parent +"Timer", get(parent + "Timer") +1 )
    
    // If timer goes over GoGrey seconds
    if (CurrentTime > GoGrey) {
      // Looper goes grey
      set("Looper" + getProp("parent", "variables").n + "ActiveColor", "#666")
    }
    // If timer hits limit
    if (CurrentTime == ( get("MaxTime") )) {
      clearInterval()  
    }
  }, 1000) // every 1 s
  
}
else {
    // Set time fader to 0
    set(getProp("parent", "id") +"Timer", 0)
}
  



No, variables declared in scripts using var statements are isolated from other scripts.

Is there a better way to structure these if statements?

It doesn't look so bad :), though I'm not sure what the last one is for (do you need the interval to run after GoGrey is reached ?)

how can I cancel the setInterval timer from outside the timer? (Like from the 'erase' button)

Currently you can't in a non hacky way, the proper way to go would be to have a script widget that can receive values from different buttons and act depending on what it receives (the buttons would only send their value to the script widget that decides what to do). That being said, it would make sense to extend clearInterval and clearTimeout to allow specifying a widget id.

But I'm getting weird behaviour

Adding some console.log() calls to your scripts should help you figure out what 's going on exactly:

console.log(getProp('this','id') + ' says: hi')
console.log(getProp('this','id') + ' says: starting loop')
// etc

The console can be opened with ctrl+k (cmd+k on mac)

Thanks!

(do you need the interval to run after GoGrey is reached ?)

Yep! After GoGrey I want the interval to keep going, then stop when it reaches MaxTime.

the proper way to go would be to have a script widget that can receive values from different buttons and act depending on what it receives (the buttons would only send their value to the script widget that decides what to do).

OK ... so I could have an if statement that checks a button status outside the script, and closes the interval?

More something like

if (value == 'turnGrey') {
  // setInterval
} else if (value == 'cancelGrey') {
  // clearInterval
}

with a button sending "turnGrey" and another sending "cancelGrey" for example. Your solution could work too but since your interval runs only once per second it might not feel reactive enough.

OK thanks - Fortunately here it doesn't need to be too snappy. When I change to else ifs... the "Play button" condition doesn't break the loop. I've got:

  1. If time = maxtime, clearInterval
  2. If play button === 0, clearInterval
  3. If time = 60s less than maxtime, goGrey

Different ordering needed?

    // Simplify syntax
    var parent = getProp("parent", "id")
    var CurrentTime = get(parent + "Timer")
    
    // Increment Timer fader
    set (parent +"Timer", get(parent + "Timer") +1 )
    
    // Test
    console.log (CurrentTime)
    
    var n = getProp("parent", "variables").n
    var playButton = "Looper" + n + "Controlsaction_rowplay_columnPlayOn"
    
    // BIG IF starts here /////////
    
    // Stop if timer hits limit
    if (CurrentTime == ( get("MaxTime") )) {
      
      console.log ("Max")
      
      // Stop loop
      clearInterval()
      console.log ("Stopped loop")
      
      // Change looper color
      set("Looper" + getProp("parent", "variables").n + "ActiveColor", "#559")
      
      // Turn off Play 
      set(playButton, 0)
      console.log ("Turned off Play")
    }

    // Stop if play 'off'
    else if (playButton === 0) {
      clearInterval()
      console.log ("Stopped loop 'cos Play was off")
    }
    
    // If timer goes over GoGrey seconds
    else if (CurrentTime > GoGrey) {
      // Looper goes grey
      set("Looper" + getProp("parent", "variables").n + "ActiveColor", "#666")
    }
    
  }, 1000) // every 1 s

else if is not always the way to go, if you want multiple conditions to be evaluated, use if (if the 1st if condition is met, the following else ifs will be skipped).

hm OK thanks... seems my problem might be weirder! Just did some tests with that 'syntax simplifying' bit.

Here's how I'm doing it:

var n = getProp("parent", "variables").n
var playButton = "Looper" + n + "Controlsaction_rowplay_columnPlayOn"

I made a console test with the above variable and a hard coded string like so:

console.log ("Play status for" + playButton + " = " + get("playButton"))
console.log ("Play status for" + "Looper1Controlsaction_rowplay_columnPlayOn" + " = " + get("Looper1Controlsaction_rowplay_columnPlayOn"))

And the results look like this!

So ... something broken in the way I made playButton?

That's only going to retrieve the value of widget with id "playButton", you probably want to remove the quotes here.

Haha sorry!

Gods I've fixed it. Ignore me!!

var playButton = get("Looper" + n + "Controlsaction_rowplay_columnPlayOn")