From 4d2114aef9e1e7570f3c2031245134e764f0ea74 Mon Sep 17 00:00:00 2001 From: Andrei Date: Mon, 17 Jul 2017 07:00:35 -0700 Subject: [PATCH] Add built-in Playable queue --- disco/voice/player.py | 6 +++--- disco/voice/queue.py | 31 +++++++++++++++++++++++++++++++ tests/tests_voice_queue.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 disco/voice/queue.py create mode 100644 tests/tests_voice_queue.py diff --git a/disco/voice/player.py b/disco/voice/player.py index bc1add2..56c023c 100644 --- a/disco/voice/player.py +++ b/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 diff --git a/disco/voice/queue.py b/disco/voice/queue.py new file mode 100644 index 0000000..e71c612 --- /dev/null +++ b/disco/voice/queue.py @@ -0,0 +1,31 @@ +import abc +import six +import gevent + + +@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) diff --git a/tests/tests_voice_queue.py b/tests/tests_voice_queue.py new file mode 100644 index 0000000..5af4cdb --- /dev/null +++ b/tests/tests_voice_queue.py @@ -0,0 +1,28 @@ +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_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)