Merge pull request #119 from jodal/feature/event-listeners
feature/event-listeners part 2
This commit is contained in:
commit
c686041de8
@ -8,6 +8,10 @@ This change log is used to track all major changes to Mopidy.
|
||||
v0.6.0 (in development)
|
||||
=======================
|
||||
|
||||
**Important changes**
|
||||
|
||||
- Pykka 0.12.3 or greater is required.
|
||||
|
||||
**Changes**
|
||||
|
||||
- Replace :attr:`mopidy.backends.base.Backend.uri_handlers` with
|
||||
|
||||
@ -25,7 +25,7 @@ Otherwise, make sure you got the required dependencies installed.
|
||||
|
||||
- Python >= 2.6, < 3
|
||||
|
||||
- `Pykka <http://jodal.github.com/pykka/>`_ >= 0.12
|
||||
- `Pykka <http://jodal.github.com/pykka/>`_ >= 0.12.3
|
||||
|
||||
- GStreamer >= 0.10, with Python bindings. See :doc:`gstreamer`.
|
||||
|
||||
|
||||
@ -461,32 +461,30 @@ class PlaybackController(object):
|
||||
self.current_cp_track = None
|
||||
|
||||
def _trigger_started_playing_event(self):
|
||||
"""
|
||||
Notifies implementors of :class:`mopidy.listeners.BackendListener` that
|
||||
a track has started playing.
|
||||
|
||||
For internal use only. Should be called by the backend directly after a
|
||||
track has started playing.
|
||||
"""
|
||||
logger.debug(u'Triggering started playing event')
|
||||
if self.current_track is None:
|
||||
return
|
||||
for listener_ref in ActorRegistry.get_by_class(BackendListener):
|
||||
listener_ref.proxy().started_playing(track=self.current_track)
|
||||
ActorRegistry.broadcast({
|
||||
'command': 'pykka_call',
|
||||
'attr_path': ('started_playing',),
|
||||
'args': [],
|
||||
'kwargs': {'track': self.current_track},
|
||||
}, target_class=BackendListener)
|
||||
|
||||
def _trigger_stopped_playing_event(self):
|
||||
"""
|
||||
Notifies implementors of :class:`mopidy.listeners.BackendListener` that
|
||||
a track has stopped playing.
|
||||
|
||||
For internal use only. Should be called by the backend before a track
|
||||
is stopped playing, e.g. at the next, previous, and stop actions and at
|
||||
end-of-track.
|
||||
"""
|
||||
# TODO Test that this is called on next/prev/end-of-track
|
||||
logger.debug(u'Triggering stopped playing event')
|
||||
if self.current_track is None:
|
||||
return
|
||||
for listener_ref in ActorRegistry.get_by_class(BackendListener):
|
||||
listener_ref.proxy().stopped_playing(
|
||||
track=self.current_track, stop_position=self.time_position)
|
||||
ActorRegistry.broadcast({
|
||||
'command': 'pykka_call',
|
||||
'attr_path': ('stopped_playing',),
|
||||
'args': [],
|
||||
'kwargs': {
|
||||
'track': self.current_track,
|
||||
'time_position': self.time_position,
|
||||
},
|
||||
}, target_class=BackendListener)
|
||||
|
||||
|
||||
class BasePlaybackProvider(object):
|
||||
|
||||
@ -20,7 +20,7 @@ class BackendListener(object):
|
||||
"""
|
||||
pass
|
||||
|
||||
def stopped_playing(self, track, stop_position):
|
||||
def stopped_playing(self, track, time_position):
|
||||
"""
|
||||
Called whenever playback is stopped.
|
||||
|
||||
@ -28,7 +28,7 @@ class BackendListener(object):
|
||||
|
||||
:param track: the track that was played before playback stopped
|
||||
:type track: :class:`mopidy.models.Track`
|
||||
:param stop_position: the time position when stopped in milliseconds
|
||||
:type stop_position: int
|
||||
:param time_position: the time position in milliseconds
|
||||
:type time_position: int
|
||||
"""
|
||||
pass
|
||||
|
||||
@ -1 +1 @@
|
||||
Pykka >= 0.12
|
||||
Pykka >= 0.12.3
|
||||
|
||||
45
tests/backends/events_test.py
Normal file
45
tests/backends/events_test.py
Normal file
@ -0,0 +1,45 @@
|
||||
import threading
|
||||
import unittest
|
||||
|
||||
from pykka.actor import ThreadingActor
|
||||
from pykka.registry import ActorRegistry
|
||||
|
||||
from mopidy.backends.dummy import DummyBackend
|
||||
from mopidy.listeners import BackendListener
|
||||
from mopidy.models import Track
|
||||
|
||||
class BackendEventsTest(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.events = {
|
||||
'started_playing': threading.Event(),
|
||||
'stopped_playing': threading.Event(),
|
||||
}
|
||||
self.backend = DummyBackend.start().proxy()
|
||||
self.listener = DummyBackendListener.start(self.events).proxy()
|
||||
|
||||
def tearDown(self):
|
||||
ActorRegistry.stop_all()
|
||||
|
||||
def test_play_sends_started_playing_event(self):
|
||||
self.backend.current_playlist.add([Track(uri='a')])
|
||||
self.backend.playback.play()
|
||||
self.events['started_playing'].wait(timeout=1)
|
||||
self.assertTrue(self.events['started_playing'].is_set())
|
||||
|
||||
def test_stop_sends_stopped_playing_event(self):
|
||||
self.backend.current_playlist.add([Track(uri='a')])
|
||||
self.backend.playback.play()
|
||||
self.backend.playback.stop()
|
||||
self.events['stopped_playing'].wait(timeout=1)
|
||||
self.assertTrue(self.events['stopped_playing'].is_set())
|
||||
|
||||
|
||||
class DummyBackendListener(ThreadingActor, BackendListener):
|
||||
def __init__(self, events):
|
||||
self.events = events
|
||||
|
||||
def started_playing(self, track):
|
||||
self.events['started_playing'].set()
|
||||
|
||||
def stopped_playing(self, track, time_position):
|
||||
self.events['stopped_playing'].set()
|
||||
Loading…
Reference in New Issue
Block a user