Events: Break out and non-exhaust context body structs (#54)

This PR makes many of the types under `EventContext` separate `#[non_exhaustive]` structs. This makes it more feasible to add further information to connection and packet events as required in future. On this note, driver (re)connection events now include the SSRC supplied by Discord and the domain name which was connected to.

In addition, this fixes global timed events to return a list of all live tracks, and extensively details/documents events at a high level.

This was tested using `cargo make ready`.
This commit is contained in:
Kyle Simpson
2021-04-07 12:52:05 +01:00
parent 1bfee1b989
commit 27f26ade99
14 changed files with 321 additions and 129 deletions

View File

@@ -1,4 +1,51 @@
//! Events relating to tracks, timing, and other callers.
//!
//! ## Listening for events
//! Driver events in Songbird are composed of two parts:
//! * An [`Event`] to listen out for. These may be discrete events,
//! or generated by timers.
//! * An [`EventHandler`] to be called on receipt of an event. As event
//! handlers may be shared between several events, the handler is called
//! with an [`EventContext`] describing which event was fired.
//!
//! Event handlers are registered using functions such as [`Driver::add_global_event`],
//! or [`TrackHandle::add_event`], or. Internally, these pairs are stored
//! as [`EventData`].
//!
//! ## `EventHandler` lifecycle
//! An event handler is essentially just an async function which may return
//! another type of event to listen out for (an `Option<Event>`). For instance,
//! [`Some(Event::Cancel)`] will remove that event listener, while `None` won't
//! change it at all.
//!
//! The exception is one-off events like [`Event::Delayed`], which remove themselves
//! after one call *unless* an [`Event`] override is returned.
//!
//! ## Global and local listeners
//! *Global* event listeners are those which are placed onto the [`Driver`],
//! while *local* event listeners are those which are placed on a
//! [`Track`]/[`Handle`].
//!
//! Track or timed events, when local, return a reference to the parent track.
//! When registered globally, they fire on a per-tick basis, returning references to
//! all relevant tracks in that 20ms window. Global/local timed events use a global
//! timer or a [track's playback time], respectively.
//!
//! [`CoreEvent`]s may only be registered globally.
//!
//! [`Event`]: Event
//! [`EventHandler`]: EventHandler
//! [`EventContext`]: EventContext
//! [`Driver::add_global_event`]: crate::driver::Driver::add_global_event
//! [`Driver`]: crate::driver::Driver::add_global_event
//! [`TrackHandle::add_event`]: crate::tracks::TrackHandle::add_event
//! [`Track`]: crate::tracks::Track::events
//! [`Handle`]: crate::tracks::TrackHandle::add_event
//! [`EventData`]: EventData
//! [`Some(Event::Cancel)`]: Event::Cancel
//! [`Event::Delayed`]: Event::Delayed
//! [track's playback time]: crate::tracks::TrackState::play_time
//! [`CoreEvent`]: CoreEvent
mod context;
mod core;
@@ -7,8 +54,15 @@ mod store;
mod track;
mod untimed;
pub use self::{context::EventContext, core::*, data::*, store::*, track::*, untimed::*};
pub(crate) use context::CoreContext;
pub use self::{
context::{context_data, EventContext},
core::*,
data::*,
store::*,
track::*,
untimed::*,
};
pub(crate) use context::{internal_data, CoreContext};
use async_trait::async_trait;
use std::time::Duration;
@@ -30,9 +84,9 @@ pub trait EventHandler: Send + Sync {
/// or stops. In case this is required, global events are a better
/// fit.
///
/// Event handlers themselves are described in [`EventData::action`].
/// Event handlers themselves are described in [`EventData::new`].
///
/// [`EventData::action`]: EventData::action
/// [`EventData::new`]: EventData::new
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum Event {