Author Topic: Basic Python Q: My problem with For loops  (Read 1113 times)

uncivil engineer

  • Wizard
  • *****
  • Posts: 118
  • Alan
    • View Profile
Basic Python Q: My problem with For loops
« on: March 24, 2015, 01:23:06 AM »
I am finding myself more and more reliant on using For loops for my programming, and this is leading to a problem.

I wrote a short mode that runs my sound board, and it has a method that takes intergers between 1 and 31 and uses the drivers to call the sound board to produce the sound.

It is called like this:  self.game.sound_mode.playsound(x)

Now if I want to cycle through each sound, I would like to do something like this:

Code: [Select]

for x in range(1:32):
    self.game.sound_mode.playsound(x)

The obvious problem is the code one computer executes so fast, the sounds never get made.  If I try to use a delay call:

Code: [Select]
self.delay(delay=2.0, handler=self.delayed_handler)

The coil calls get stacked up on top of each other, as fast as the For loop can place them in the stack, and still don't get executed properly.

So is there a way to slow down For loops without resorting to the time.sleep() command, that I understand will bring the game loop to a screeching halt?

When I do my bonus mode, I know I will need to use this delay method so I can count down the bonus lights as I add the bonus to the player score.
Thanks,
Uncivil Engineer

PS. California welcomed me back tonight with a 3.5 earthquake!
http://earthquake.usgs.gov/earthquakes/eventpage/ci37347128#general_summary


Brian Madden

  • Wizard
  • *****
  • Posts: 498
  • Mission Pinball
    • View Profile
    • Mission Pinball
Re: Basic Python Q: My problem with For loops
« Reply #1 on: March 24, 2015, 01:33:03 AM »
You can't really slow down your code since that will slow down your entire loop which will cause delays with switch responses, potentially watchdog timeouts, etc. So definitely don't want to do that.

If you wanted something that could sleep then you could make that loop its own thread and let it sleep while it was waiting, but meh, multithreaded programming will introduce more headaches which will make you want to bash your head against a wall, so you don't want to do that either.

The "real" way to do this is to make it so the next sound is called after the first one ends. In your case, are these software generated sounds or is this a WPC audio board that you're playing stuff from? If you knew how long each sound was, you could play one and then set a delay and have your delay callback manually increment a pointer and then lookup the duration of the sound at the current index, play it, set the delay, and repeat.

And a 3.5? Pfft. Up here we don't even get out of bed for anything under a 5! :)
Brian
The Mission Pinball Framework (MPF) Project*
Twitter
* Disclaimer: MPF is a work-in-progress!

MOcean

  • P3 Developers
  • *
  • Posts: 820
  • Michael Ocean
    • View Profile
Re: Basic Python Q: My problem with For loops
« Reply #2 on: March 24, 2015, 10:20:10 AM »
I was thinking about this while working on something else... since the editor was open... well, maybe this will work.

Look at it and ask questions :)

EDIT: I just looked at your other thread and saw that you do not drive your sound board simply by calling enable, so that will NEED to change!

Code: [Select]
class SoundMode(Mode):
    last_driver = None
    queue_length = 0

    def __init__(self):
        super(SoundMode,Mode).__init__()       
        self.last_driver = None
        self.queue_length = 0

    def stop(self):
        if(last_driver is not None):
            self.game.coils[last_driver].disable()
            self.cancel_delayed(name='play_next')
            self.queue_length = 0

    def play(self, sound, length, now=False):
        if(now):
            self.stop()
        self.doplay((sound,length))

    def doplay(self, (sound, length)):
        if(queue_length == 0):
            self.last_driver = sound
            self.queue_length = length
            self.game.coils[last_driver].enable() # should this be pulse?? not sure how your board works!
        else:
            self.delay(name='play_next',
                   event_type=None,
                   delay=self.queue_length,
                   handler=self.doplay,
                   param=(sound,length))
            self.queue_length = self.queue_length + length
« Last Edit: March 24, 2015, 10:27:27 AM by MOcean »