mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-05 02:39:53 +02:00
Shuffle tracks in place (#1445)
* connect: add shuffle_vec.rs * connect: shuffle in place * add shuffle with seed option * reduce complexity to add new metadata fields * add context index to metadata * use seed for shuffle When losing the connection and restarting the dealer, the seed is now stored in the context metadata. So on transfer we can pickup the seed again and shuffle the context as it was previously * add log for shuffle seed * connect: use small_rng, derive Default * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
471735aa5a
commit
34762f2274
12 changed files with 314 additions and 170 deletions
|
@ -4,13 +4,10 @@ use crate::{
|
|||
autoplay_context_request::AutoplayContextRequest, context::Context,
|
||||
transfer_state::TransferState,
|
||||
},
|
||||
state::{
|
||||
context::{ContextType, UpdateContext},
|
||||
ConnectState,
|
||||
},
|
||||
state::{context::ContextType, ConnectState},
|
||||
};
|
||||
use std::cmp::PartialEq;
|
||||
use std::{
|
||||
cmp::PartialEq,
|
||||
collections::{HashMap, VecDeque},
|
||||
fmt::{Display, Formatter},
|
||||
hash::Hash,
|
||||
|
@ -35,7 +32,7 @@ pub(super) enum ContextAction {
|
|||
pub(super) struct ResolveContext {
|
||||
resolve: Resolve,
|
||||
fallback: Option<String>,
|
||||
update: UpdateContext,
|
||||
update: ContextType,
|
||||
action: ContextAction,
|
||||
}
|
||||
|
||||
|
@ -44,7 +41,7 @@ impl ResolveContext {
|
|||
Self {
|
||||
resolve: Resolve::Uri(uri.into()),
|
||||
fallback: None,
|
||||
update: UpdateContext::Default,
|
||||
update: ContextType::Default,
|
||||
action: ContextAction::Append,
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +49,7 @@ impl ResolveContext {
|
|||
pub fn from_uri(
|
||||
uri: impl Into<String>,
|
||||
fallback: impl Into<String>,
|
||||
update: UpdateContext,
|
||||
update: ContextType,
|
||||
action: ContextAction,
|
||||
) -> Self {
|
||||
let fallback_uri = fallback.into();
|
||||
|
@ -64,7 +61,7 @@ impl ResolveContext {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_context(context: Context, update: UpdateContext, action: ContextAction) -> Self {
|
||||
pub fn from_context(context: Context, update: ContextType, action: ContextAction) -> Self {
|
||||
Self {
|
||||
resolve: Resolve::Context(context),
|
||||
fallback: None,
|
||||
|
@ -214,7 +211,7 @@ impl ContextResolver {
|
|||
let (next, resolve_uri, _) = self.find_next().ok_or(ContextResolverError::NoNext)?;
|
||||
|
||||
match next.update {
|
||||
UpdateContext::Default => {
|
||||
ContextType::Default => {
|
||||
let mut ctx = self.session.spclient().get_context(resolve_uri).await;
|
||||
if let Ok(ctx) = ctx.as_mut() {
|
||||
ctx.uri = Some(next.context_uri().to_string());
|
||||
|
@ -223,7 +220,7 @@ impl ContextResolver {
|
|||
|
||||
ctx
|
||||
}
|
||||
UpdateContext::Autoplay => {
|
||||
ContextType::Autoplay => {
|
||||
if resolve_uri.contains("spotify:show:") || resolve_uri.contains("spotify:episode:")
|
||||
{
|
||||
// autoplay is not supported for podcasts
|
||||
|
@ -304,13 +301,13 @@ impl ContextResolver {
|
|||
}
|
||||
|
||||
match (next.update, state.active_context) {
|
||||
(UpdateContext::Default, ContextType::Default) | (UpdateContext::Autoplay, _) => {
|
||||
(ContextType::Default, ContextType::Default) | (ContextType::Autoplay, _) => {
|
||||
debug!(
|
||||
"last item of type <{:?}>, finishing state setup",
|
||||
next.update
|
||||
);
|
||||
}
|
||||
(UpdateContext::Default, _) => {
|
||||
(ContextType::Default, _) => {
|
||||
debug!("skipped finishing default, because it isn't the active context");
|
||||
return false;
|
||||
}
|
||||
|
@ -320,7 +317,7 @@ impl ContextResolver {
|
|||
let res = if let Some(transfer_state) = transfer_state.take() {
|
||||
state.finish_transfer(transfer_state)
|
||||
} else if state.shuffling_context() {
|
||||
state.shuffle()
|
||||
state.shuffle(None)
|
||||
} else if matches!(active_ctx, Ok(ctx) if ctx.index.track == 0) {
|
||||
// has context, and context is not touched
|
||||
// when the index is not zero, the next index was already evaluated elsewhere
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue