Browse Source

[voice] Better Queue (#44)

* Add built-in Playable queue

* More functionality
pull/46/head
Andrei Zbikowski 8 years ago
committed by GitHub
parent
commit
667eb1be3b
  1. 2
      disco/voice/client.py
  2. 6
      disco/voice/player.py
  3. 50
      disco/voice/queue.py
  4. 66
      tests/tests_voice_queue.py

2
disco/voice/client.py

@ -226,7 +226,7 @@ class VoiceClient(LoggingClass):
if self.token and self.token != data.token:
return
self.log.info('[%s] Recieved VOICE_SERVER_UPDATE (state = %s)', self, self.state)
self.log.info('[%s] Recieved VOICE_SERVER_UPDATE (state = %s / endpoint = %s)', self, self.state, data.endpoint)
self.token = data.token
self.set_state(VoiceState.AUTHENTICATING)

6
disco/voice/player.py

@ -1,11 +1,11 @@
import time
import gevent
from six.moves import queue
from holster.enum import Enum
from holster.emitter import Emitter
from disco.voice.client import VoiceState
from disco.voice.queue import PlayableQueue
MAX_TIMESTAMP = 4294967295
@ -19,11 +19,11 @@ class Player(object):
'DISCONNECT'
)
def __init__(self, client):
def __init__(self, client, queue=None):
self.client = client
# Queue contains playable items
self.queue = queue.Queue()
self.queue = queue or PlayableQueue()
# Whether we're playing music (true for lifetime)
self.playing = True

50
disco/voice/queue.py

@ -0,0 +1,50 @@
import abc
import six
import gevent
import random
@six.add_metaclass(abc.ABCMeta)
class BaseQueue(object):
@abc.abstractmethod
def get(self):
raise NotImplementedError
class PlayableQueue(BaseQueue):
def __init__(self):
self._data = []
self._event = gevent.event.Event()
def append(self, item):
self._data.append(item)
if self._event:
self._event.set()
self._event = None
def _get(self):
if not len(self._data):
if not self._event:
self._event = gevent.event.Event()
self._event.wait()
return self._get()
return self._data.pop(0)
def get(self):
return self._get()
def shuffle(self):
random.shuffle(self._data)
def clear(self):
self._data = []
def __len__(self):
return len(self._data)
def __iter__(self):
return self._data.__iter__()
def __nonzero__(self):
return True

66
tests/tests_voice_queue.py

@ -0,0 +1,66 @@
import gevent
from unittest import TestCase
from disco.voice.queue import PlayableQueue
class TestPlayableQueue(TestCase):
def test_append(self):
q = PlayableQueue()
q.append(1)
q.append(2)
q.append(3)
self.assertEqual(q._data, [1, 2, 3])
self.assertEqual(q.get(), 1)
self.assertEqual(q.get(), 2)
self.assertEqual(q.get(), 3)
def test_len(self):
q = PlayableQueue()
for idx in range(1234):
q.append(idx)
self.assertEqual(len(q), 1234)
def test_iter(self):
q = PlayableQueue()
for idx in range(5):
q.append(idx)
self.assertEqual(sum(q), 10)
def test_blocking_get(self):
q = PlayableQueue()
result = gevent.event.AsyncResult()
def get():
result.set(q.get())
gevent.spawn(get)
q.append(5)
self.assertEqual(result.get(), 5)
def test_shuffle(self):
q = PlayableQueue()
for idx in range(10000):
q.append(idx)
self.assertEqual(q._data[0], 0)
q.shuffle()
self.assertNotEqual(q._data[0], 0)
def test_clear(self):
q = PlayableQueue()
for idx in range(100):
q.append(idx)
self.assertEqual(q._data[0], 0)
self.assertEqual(q._data[-1], 99)
self.assertEqual(len(q), 100)
q.clear()
self.assertEqual(len(q), 0)
Loading…
Cancel
Save