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: if self.token and self.token != data.token:
return 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.token = data.token
self.set_state(VoiceState.AUTHENTICATING) self.set_state(VoiceState.AUTHENTICATING)

6
disco/voice/player.py

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