/** * Start the simulation. */ @Override public final void start() { checkState(!isTicking(), "Time is already ticking."); isTicking = true; eventDispatcher.dispatchEvent(new Event(ClockEventType.STARTED, this)); doStart(); eventDispatcher.dispatchEvent(new Event(ClockEventType.STOPPED, this)); }
final void tickImpl() { for (final TickListener t : tickListeners) { timeLapse.reset(); t.tick(timeLapse); } // in the after tick the TimeLapse can no longer be consumed timeLapse.consumeAll(); for (final TickListener t : tickListeners) { t.afterTick(timeLapse); } // advance time timeLapse.next(); if (Thread.interrupted() && isTicking()) { LOGGER.info("Simulation interrupted after tick {}, stopping.", timeLapse); stop(); } }
/** * Test static properties of time model. */ @Test public void testDefaultProperties() { assertThat(getModel().getTickListeners()).isEmpty(); assertThat(getModel().getCurrentTime()).isEqualTo(0L); assertThat(getModel().isTicking()).isFalse(); }
/** * Tests that time lapses provided via the listener are behaving as they * should. */ @Test public void timeLapseSafety() { final List<IllegalArgumentException> failures = new ArrayList<>(); getModel().register(new LimitingTickListener(getModel(), 3)); getModel().register(new TickListener() { @Override public void tick(TimeLapse timeLapse) { timeLapse.consume(1L); } @Override public void afterTick(TimeLapse timeLapse) { try { timeLapse.consume(1L); } catch (final IllegalArgumentException e) { failures.add(e); } } }); getModel().start(); assertThat(getModel().isTicking()).isFalse(); assertThat(failures).hasSize(3); }