protected function trackStopped(SSLTrack $track)
 {
     $stm = $this->factory->newScrobblerTrackModel($track);
     if ($stm->isScrobblable()) {
         L::level(L::INFO) && L::log(L::INFO, __CLASS__, 'I reckon it\'s time to submit a scrobble for %s!', array($track->getFullTitle()));
         $this->notifyScrobbleObservers($track);
     }
 }
 protected function startTrack(SSLTrack $started_track)
 {
     $started_row = $started_track->getRow();
     foreach ($this->now_playing_queue as $i => $scrobble_model) {
         /* @var $scrobble_model ScrobblerTrackModel */
         if ($scrobble_model->getRow() == $started_row) {
             // do not double-add to the queue.
             return;
         }
     }
     // Put new tracks last in the queue for the purposes of determining what's now playing.
     // This means that tracks should transition to "Now Playing" when the previous track is stopped or taken off the deck.
     $scrobble_model = $this->factory->newScrobblerTrackModel($started_track);
     $scrobble_model_row = $scrobble_model->getRow();
     if ($scrobble_model_row != $started_row) {
         throw new RuntimeException("Row mismatch! Asked for {$started_row}, got {$scrobble_model_row}");
     }
     $this->now_playing_queue[] = $scrobble_model;
     L::level(L::INFO) && L::log(L::INFO, __CLASS__, 'enqueued track %s', array($started_track->getFullTitle()));
     L::level(L::DEBUG) && L::log(L::DEBUG, __CLASS__, 'queue length is now %d', array(count($this->now_playing_queue)));
 }
 public function newScrobblerTrackModel(SSLTrack $track)
 {
     $this->call_count++;
     $track_row = $track->getRow();
     $this->decks[$track_row] = parent::newScrobblerTrackModel($track);
     return $this->decks[$track_row];
 }