private void bufferToNextPosition() { log.info("Buffering to next position: {}", nextStartingPosition); int i = 0; Snapshot reqSnapshot = null; Snapshot prevSnapshot = null; for (Snapshot snapshot : timeline.getSnapshots()) { long offset = timeline.getOffset(snapshot.getSamplingTime()); log.debug("Snapshot {} has offset {}", i, offset); if (offset >= nextStartingPosition) { if (prevSnapshot == null) { reqSnapshot = snapshot; } else { reqSnapshot = prevSnapshot; } break; } prevSnapshot = snapshot; i++; } if (reqSnapshot == null) { reqSnapshot = prevSnapshot; if (reqSnapshot == null) { log.error("Could not find snapshot for offset {}", nextStartingPosition); setPlayState(PlayState.PAUSED); return; } } // Initialize the state at the closest possible snapshot log.info( "Init with snapshot with offset {}", timeline.getOffset(reqSnapshot.getSamplingTime())); this.state = new GridState(reqSnapshot, "runState"); initState(); // Apply all events between the closet snapshot and the desired starting position this.totalElapsed = timeline.getOffset((reqSnapshot.getSamplingTime())) + 1; // This must be set before calling updateState for the first time after changing the position // (i.e. totalElapsed) this.prevElapsed = totalElapsed; long elapsed = nextStartingPosition - totalElapsed; if (elapsed < 0) { log.warn( "Negative time elapsed. Normalizing to nextStartingPosition={}", nextStartingPosition); totalElapsed = nextStartingPosition; elapsed = nextStartingPosition; } log.info("Buffering elapsed: {}", elapsed); this.tweenChanges = false; updateState(elapsed); this.tweenChanges = true; // Get ready to start playing this.lastSliceRequestDate = new Date(); if (totalElapsed != nextStartingPosition) { totalElapsed = nextStartingPosition; } setPlayState(PlayState.READY); log.info("Buffered at totalElapsed={}", totalElapsed); }