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"
|
version = "0.2"
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
|
[dependencies.typemap_rev]
|
||||||
|
optional = true
|
||||||
|
version = "0.1"
|
||||||
|
|
||||||
[dependencies.url]
|
[dependencies.url]
|
||||||
optional = true
|
optional = true
|
||||||
version = "2"
|
version = "2"
|
||||||
@@ -140,6 +144,7 @@ driver = [
|
|||||||
"tokio/rt-core",
|
"tokio/rt-core",
|
||||||
"tokio/sync",
|
"tokio/sync",
|
||||||
"tokio/time",
|
"tokio/time",
|
||||||
|
"typemap_rev",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"xsalsa20poly1305",
|
"xsalsa20poly1305",
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ pub use audiopus::{self as opus, Bitrate};
|
|||||||
pub use discortp as packet;
|
pub use discortp as packet;
|
||||||
#[cfg(feature = "driver")]
|
#[cfg(feature = "driver")]
|
||||||
pub use serenity_voice_model as model;
|
pub use serenity_voice_model as model;
|
||||||
|
#[cfg(feature = "driver")]
|
||||||
|
pub use typemap_rev as typemap;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use utils as test_utils;
|
use utils as test_utils;
|
||||||
|
|||||||
@@ -3,29 +3,45 @@ use crate::{
|
|||||||
events::{Event, EventData, EventHandler},
|
events::{Event, EventData, EventHandler},
|
||||||
input::Metadata,
|
input::Metadata,
|
||||||
};
|
};
|
||||||
use std::{sync::Arc, time::Duration};
|
use std::{fmt, sync::Arc, time::Duration};
|
||||||
use tokio::sync::{mpsc::UnboundedSender, oneshot};
|
use tokio::sync::{mpsc::UnboundedSender, oneshot, RwLock};
|
||||||
|
use typemap_rev::TypeMap;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[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.
|
/// 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
|
/// 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
|
/// [`Track`]: Track
|
||||||
pub struct TrackHandle {
|
pub struct TrackHandle {
|
||||||
inner: Arc<InnerHandle>,
|
inner: Arc<InnerHandle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
struct InnerHandle {
|
struct InnerHandle {
|
||||||
command_channel: UnboundedSender<TrackCommand>,
|
command_channel: UnboundedSender<TrackCommand>,
|
||||||
seekable: bool,
|
seekable: bool,
|
||||||
metadata: Box<Metadata>,
|
|
||||||
uuid: Uuid,
|
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 {
|
impl TrackHandle {
|
||||||
@@ -42,8 +58,9 @@ impl TrackHandle {
|
|||||||
let inner = Arc::new(InnerHandle {
|
let inner = Arc::new(InnerHandle {
|
||||||
command_channel,
|
command_channel,
|
||||||
seekable,
|
seekable,
|
||||||
metadata,
|
|
||||||
uuid,
|
uuid,
|
||||||
|
metadata,
|
||||||
|
typemap: RwLock::new(TypeMap::new()),
|
||||||
});
|
});
|
||||||
|
|
||||||
Self { inner }
|
Self { inner }
|
||||||
@@ -209,6 +226,17 @@ impl TrackHandle {
|
|||||||
&self.inner.metadata
|
&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]
|
#[inline]
|
||||||
/// Send a raw command to the [`Track`] object.
|
/// 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())
|
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
|
/// [`create_player`]: create_player
|
||||||
|
/// [`Track`]: Track
|
||||||
|
/// [`TrackHandle`]: TrackHandle
|
||||||
pub fn create_player_with_uuid(source: Input, uuid: Uuid) -> (Track, TrackHandle) {
|
pub fn create_player_with_uuid(source: Input, uuid: Uuid) -> (Track, TrackHandle) {
|
||||||
let (tx, rx) = mpsc::unbounded_channel();
|
let (tx, rx) = mpsc::unbounded_channel();
|
||||||
let can_seek = source.is_seekable();
|
let can_seek = source.is_seekable();
|
||||||
|
|||||||
Reference in New Issue
Block a user