Tracks: Add TypeMap to Handles.
Adds a shared TypeMap per TrackHandle. This should greatly simplify the user experience for attaching additional per-track state which the driver does not care for.
This commit is contained in:
@@ -91,6 +91,10 @@ optional = true
|
||||
version = "0.2"
|
||||
default-features = false
|
||||
|
||||
[dependencies.typemap_rev]
|
||||
optional = true
|
||||
version = "0.1"
|
||||
|
||||
[dependencies.url]
|
||||
optional = true
|
||||
version = "2"
|
||||
@@ -140,6 +144,7 @@ driver = [
|
||||
"tokio/rt-core",
|
||||
"tokio/sync",
|
||||
"tokio/time",
|
||||
"typemap_rev",
|
||||
"url",
|
||||
"uuid",
|
||||
"xsalsa20poly1305",
|
||||
|
||||
@@ -66,6 +66,8 @@ pub use audiopus::{self as opus, Bitrate};
|
||||
pub use discortp as packet;
|
||||
#[cfg(feature = "driver")]
|
||||
pub use serenity_voice_model as model;
|
||||
#[cfg(feature = "driver")]
|
||||
pub use typemap_rev as typemap;
|
||||
|
||||
#[cfg(test)]
|
||||
use utils as test_utils;
|
||||
|
||||
@@ -3,29 +3,45 @@ use crate::{
|
||||
events::{Event, EventData, EventHandler},
|
||||
input::Metadata,
|
||||
};
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tokio::sync::{mpsc::UnboundedSender, oneshot};
|
||||
use std::{fmt, sync::Arc, time::Duration};
|
||||
use tokio::sync::{mpsc::UnboundedSender, oneshot, RwLock};
|
||||
use typemap_rev::TypeMap;
|
||||
use uuid::Uuid;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
/// Handle for safe control of a [`Track`] track from other threads, outside
|
||||
/// Handle for safe control of a [`Track`] from other threads, outside
|
||||
/// of the audio mixing and voice handling context.
|
||||
///
|
||||
/// Almost all method calls here are fallible; in most cases, this will be because
|
||||
/// These are cheap to clone, using `Arc<...>` internally.
|
||||
///
|
||||
/// Many method calls here are fallible; in most cases, this will be because
|
||||
/// the underlying [`Track`] object has been discarded. Those which aren't refer
|
||||
/// to immutable properties of the underlying stream.
|
||||
/// to immutable properties of the underlying stream, or shared data not used
|
||||
/// by the driver.
|
||||
///
|
||||
/// [`Track`]: Track
|
||||
pub struct TrackHandle {
|
||||
inner: Arc<InnerHandle>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct InnerHandle {
|
||||
command_channel: UnboundedSender<TrackCommand>,
|
||||
seekable: bool,
|
||||
metadata: Box<Metadata>,
|
||||
uuid: Uuid,
|
||||
metadata: Box<Metadata>,
|
||||
typemap: RwLock<TypeMap>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for InnerHandle {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("InnerHandle")
|
||||
.field("command_channel", &self.command_channel)
|
||||
.field("seekable", &self.seekable)
|
||||
.field("uuid", &self.uuid)
|
||||
.field("metadata", &self.metadata)
|
||||
.field("typemap", &"<LOCK>")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl TrackHandle {
|
||||
@@ -42,8 +58,9 @@ impl TrackHandle {
|
||||
let inner = Arc::new(InnerHandle {
|
||||
command_channel,
|
||||
seekable,
|
||||
metadata,
|
||||
uuid,
|
||||
metadata,
|
||||
typemap: RwLock::new(TypeMap::new()),
|
||||
});
|
||||
|
||||
Self { inner }
|
||||
@@ -209,6 +226,17 @@ impl TrackHandle {
|
||||
&self.inner.metadata
|
||||
}
|
||||
|
||||
/// Allows access to this track's attached TypeMap.
|
||||
///
|
||||
/// TypeMaps allow additional, user-defined data shared by all handles
|
||||
/// to be attached to any track.
|
||||
///
|
||||
/// Driver code will never attempt to lock access to this map,
|
||||
/// preventing deadlock/stalling.
|
||||
pub fn typemap(&self) -> &RwLock<TypeMap> {
|
||||
&self.inner.typemap
|
||||
}
|
||||
|
||||
#[inline]
|
||||
/// Send a raw command to the [`Track`] object.
|
||||
///
|
||||
|
||||
@@ -382,9 +382,12 @@ pub fn create_player(source: Input) -> (Track, TrackHandle) {
|
||||
create_player_with_uuid(source, Uuid::new_v4())
|
||||
}
|
||||
|
||||
/// Refer to the documentation for [`create_player`] however, allows for a custom uuid to be inserted into the Track and Handle
|
||||
/// Creates a [`Track`] and [`TrackHandle`] as in [`create_player`], allowing
|
||||
/// a custom UUID to be set.
|
||||
///
|
||||
/// [`create_player`]: create_player
|
||||
/// [`Track`]: Track
|
||||
/// [`TrackHandle`]: TrackHandle
|
||||
pub fn create_player_with_uuid(source: Input, uuid: Uuid) -> (Track, TrackHandle) {
|
||||
let (tx, rx) = mpsc::unbounded_channel();
|
||||
let can_seek = source.is_seekable();
|
||||
|
||||
Reference in New Issue
Block a user