View Javadoc
1   package net.kreatious.pianoleopard.midi.track;
2   
3   import java.util.HashMap;
4   import java.util.Map;
5   import java.util.Optional;
6   
7   import javax.sound.midi.Track;
8   
9   import net.kreatious.pianoleopard.midi.event.Event;
10  import net.kreatious.pianoleopard.midi.event.EventFactory;
11  import net.kreatious.pianoleopard.midi.event.EventPair;
12  import net.kreatious.pianoleopard.midi.event.TempoCache;
13  
14  /**
15   * Decomposes a {@link Track} into {@link EventPair}s
16   *
17   * @author Jay-R Studer
18   */
19  abstract class TrackVisitor {
20      private final Map<Object, Event> incompleteEvents = new HashMap<>();
21  
22      /**
23       * Invokes this visitor on the specified track.
24       *
25       * @param track
26       *            the {@link Track} to visit
27       * @param cache
28       *            the {@link TempoCache} to use for converting timestamps
29       */
30      public void accept(Track track, TempoCache cache) {
31          for (int i = 0; i != track.size(); i++) {
32              EventFactory.create(track.get(i), cache).ifPresent(
33                      event -> {
34                          if (event.isOn()) {
35                              incompleteEvents.put(event.getSlot(), event);
36                          } else {
37                              Optional.ofNullable(incompleteEvents.remove(event.getSlot())).ifPresent(
38                                      previousOnEvent -> visitEventPair(new EventPair<>(previousOnEvent, event)));
39                          }
40                      });
41          }
42      }
43  
44      /**
45       * Called for each complete pair of events in the current track
46       *
47       * @param pair
48       *            a completed event pair
49       */
50      protected abstract void visitEventPair(EventPair<? extends Event> pair);
51  }