mixer: Add MixerListener

This commit is contained in:
Stein Magnus Jodal 2014-07-10 00:18:22 +02:00
parent 4d0fa17c85
commit b8de7fa75c
3 changed files with 102 additions and 3 deletions

View File

@ -10,6 +10,9 @@ Audio mixer API
.. autoclass:: mopidy.mixer.Mixer
:members:
.. autoclass:: mopidy.mixer.MixerListener
:members:
Mixer implementations
=====================

View File

@ -1,8 +1,16 @@
from __future__ import unicode_literals
import logging
from mopidy import listener
logger = logging.getLogger(__name__)
class Mixer(object):
"""Audio mixer API
"""
Audio mixer API
If the mixer has problems during initialization it should raise
:exc:`~mopidy.exceptions.MixerError` with a descriptive error message. This
@ -16,7 +24,8 @@ class Mixer(object):
"""
name = None
"""Name of the mixer.
"""
Name of the mixer.
Used when configuring what mixer to use. Should match the
:attr:`~mopidy.ext.Extension.ext_name` of the extension providing the
@ -54,9 +63,20 @@ class Mixer(object):
"""
return False
def trigger_volume_changed(self, volume):
"""
Send ``volume_changed`` event to all mixer listeners.
This method should be called by subclasses when the volume is changed,
either because of a call to :meth:`set_volume` or because or any
external entity changing the volume.
"""
logger.debug('Mixer event: volume_changed(volume=%d)', volume)
MixerListener.send('volume_changed', volume=volume)
def get_mute(self):
"""
Get mute status of the mixer.
Get mute state of the mixer.
*MAY be implemented by subclass.*
@ -76,3 +96,53 @@ class Mixer(object):
:rtype: :class:`True` if success, :class:`False` if failure
"""
return False
def trigger_mute_changed(self, muted):
"""
Send ``mute_changed`` event to all mixer listeners.
This method should be called by subclasses when the mute state is
changed, either because of a call to :meth:`set_mute` or because or
any external entity changing the mute state.
"""
logger.debug('Mixer event: mute_changed(muted=%s)', muted)
MixerListener.send('mute_changed', muted=muted)
class MixerListener(listener.Listener):
"""
Marker interface for recipients of events sent by the mixer actor.
Any Pykka actor that mixes in this class will receive calls to the methods
defined here when the corresponding events happen in the mixer actor. This
interface is used both for looking up what actors to notify of the events,
and for providing default implementations for those listeners that are not
interested in all events.
"""
@staticmethod
def send(event, **kwargs):
"""Helper to allow calling of audio listener events"""
listener.send_async(MixerListener, event, **kwargs)
def volume_changed(self, volume):
"""
Called after the volume has changed.
*MAY* be implemented by actor.
:param volume: the new volume
:type volume: int in range [0..100]
"""
pass
def mute_changed(self, muted):
"""
Called after the mute state has changed.
*MAY* be implemented by actor.
:param muted: :class:`True` if muted, :class:`False` if not muted
:type muted: bool
"""
pass

26
tests/test_mixer.py Normal file
View File

@ -0,0 +1,26 @@
from __future__ import unicode_literals
import unittest
import mock
from mopidy import mixer
class MixerListenerTest(unittest.TestCase):
def setUp(self):
self.listener = mixer.MixerListener()
def test_on_event_forwards_to_specific_handler(self):
self.listener.volume_changed = mock.Mock()
self.listener.on_event(
'volume_changed', volume=60)
self.listener.volume_changed.assert_called_with(volume=60)
def test_listener_has_default_impl_for_volume_changed(self):
self.listener.volume_changed(volume=60)
def test_listener_has_default_impl_for_mute_changed(self):
self.listener.mute_changed(muted=True)