/* Copyright 2006 by Sean Luke and George Mason University Licensed under the Academic Free License version 3.0 See the file "LICENSE" for more information */ package sim.engine; /** MultiStep takes an integer N, a boolean called countdown, and a steppable. EITHER the subsidiary steppable is stepped N times for each MultiStep.step(...), OR the subsidiary steppable is stepped once every N MultiStep.step(...) calls. The second one occurs if countdown is set to true. If N is <=0, then the subsidiary steppable is never stepped no matter what. <p>The count down (if we're doing that) can be reset by calling resetCountdown(). MultiStep is properly synchronized. <p>If you're using MultiStep to schedule an agent to occur repeating over time, you'd probably do better to use Schedule.scheduleRepeating(...) instead. */ public class MultiStep implements Steppable { private static final long serialVersionUID = 1; int current; final boolean countdown; final int n; final Steppable step; /** If countdown is true, then we call step.step(...) once every N times we're stepped. if countdown is false, then we call step.step(...) N times every time we're stepped.*/ public MultiStep(Steppable step, int n, boolean countdown) { if (n < 0) n = 0; this.n = n; this.step = step; this.countdown = countdown; current = n; } /** If we're counting down, then this resets the countdown. */ public synchronized void resetCountdown() { current = n; } /** If we're counting down, then this resets the countdown to the given value, which should be > 0 and <= n. Note that if n = 0, this method has no valid value you can pass in. */ public synchronized void resetCountdown(int val) { if (val <= n && val > 0) current = val; } // this allows us to jump in and out of the steppable so that the // MultiStep can be reset() even in the middle of a step(state)... synchronized boolean go() { if (--current == 0) { current = n; return true; } return false; } public void step(SimState state) { if (n == 0) { } // do nothing else if (countdown) // do once every n times { if (go()) step.step(state); } else // do n times { for(int x=0;x<n;x++) step.step(state); } } }