add Multiple action and tool to remove queue-duplicates

This commit is contained in:
Mark
2024-12-31 10:39:12 +01:00
parent a8e18abfd2
commit b1c0925647
7 changed files with 296 additions and 171 deletions

View File

@@ -527,19 +527,23 @@ impl Database {
if let Some(client) = client {
for (udepid, udep) in &mut self.update_endpoints {
if client == *udepid {
let denied =
Action::Denied(command.action.get_req().unwrap_or_else(Req::none))
.cmd(0xFFu8);
match udep {
UpdateEndpoint::Bytes(w) => {
let _ = w.write(&denied.to_bytes_vec());
let mut reqs = command.action.get_req_if_some();
if reqs.is_empty() {
reqs.push(Req::none());
}
for req in reqs {
let denied = Action::Denied(req).cmd(0xFFu8);
match udep {
UpdateEndpoint::Bytes(w) => {
let _ = w.write(&denied.to_bytes_vec());
}
UpdateEndpoint::CmdChannel(w) => {
let _ = w.send(Arc::new(denied));
}
UpdateEndpoint::Custom(w) => w(&denied),
UpdateEndpoint::CustomArc(w) => w(Arc::new(denied)),
UpdateEndpoint::CustomBytes(w) => w(&denied.to_bytes_vec()),
}
UpdateEndpoint::CmdChannel(w) => {
let _ = w.send(Arc::new(denied));
}
UpdateEndpoint::Custom(w) => w(&denied),
UpdateEndpoint::CustomArc(w) => w(Arc::new(denied)),
UpdateEndpoint::CustomBytes(w) => w(&denied.to_bytes_vec()),
}
return;
}
@@ -864,6 +868,11 @@ impl Database {
song.duration_millis = duration;
}
}
Action::Multiple(actions) => {
for action in actions {
self.apply_action_unchecked_seq(action, client);
}
}
Action::InitComplete => {
self.client_is_init = true;
}
@@ -1008,13 +1017,13 @@ impl Database {
self.seq.inc();
}
let mut update = self.seq.pack(update);
let req = update.action.take_req();
let reqs = update.action.take_req_all();
let mut remove = vec![];
let mut bytes = None;
let mut arc = None;
for (i, (udepid, udep)) in self.update_endpoints.iter_mut().enumerate() {
if req.is_some_and(|r| r.is_some()) && client.is_some_and(|v| *udepid == v) {
update.action.put_req(req.unwrap());
if reqs.iter().any(|r| r.is_some()) && client.is_some_and(|v| *udepid == v) {
update.action.put_req_all(reqs.clone());
match udep {
UpdateEndpoint::Bytes(writer) => {
if writer.write_all(&update.to_bytes_vec()).is_err() {
@@ -1035,7 +1044,7 @@ impl Database {
func(bytes.as_ref().unwrap())
}
}
update.action.take_req();
update.action.take_req_all();
}
match udep {
UpdateEndpoint::Bytes(writer) => {
@@ -1079,9 +1088,7 @@ impl Database {
self.update_endpoints.remove(i);
}
}
if let Some(req) = req {
update.action.put_req(req);
}
update.action.put_req_all(reqs);
update.action
}
pub fn sync(&mut self, artists: Vec<Artist>, albums: Vec<Album>, songs: Vec<Song>) {

View File

@@ -43,20 +43,28 @@ impl Action {
pub fn cmd(self, seq: u8) -> Command {
Command::new(seq, self)
}
pub fn take_req(&mut self) -> Option<Req> {
pub fn take_req_all(&mut self) -> Vec<Req> {
self.req_mut()
.into_iter()
.map(|r| std::mem::replace(r, Req::none()))
.collect()
}
pub fn get_req_all(&mut self) -> Vec<Req> {
self.req_mut().into_iter().map(|r| *r).collect()
}
pub fn get_req_if_some(&mut self) -> Vec<Req> {
self.req_mut()
.into_iter()
.map(|r| *r)
.filter(|r| r.is_some())
.collect()
}
pub fn get_req(&mut self) -> Option<Req> {
self.req_mut().map(|r| *r).filter(|r| r.is_some())
}
pub fn put_req(&mut self, req: Req) {
if let Some(r) = self.req_mut() {
*r = req;
pub fn put_req_all(&mut self, reqs: Vec<Req>) {
for (o, n) in self.req_mut().into_iter().zip(reqs) {
*o = n;
}
}
fn req_mut(&mut self) -> Option<&mut Req> {
fn req_mut(&mut self) -> Vec<&mut Req> {
match self {
Self::QueueUpdate(_, _, req)
| Self::QueueAdd(_, _, req)
@@ -68,7 +76,7 @@ impl Action {
| Self::ModifySong(_, req)
| Self::ModifyAlbum(_, req)
| Self::ModifyArtist(_, req)
| Self::Denied(req) => Some(req),
| Self::Denied(req) => vec![req],
Self::Resume
| Self::Pause
| Self::Stop
@@ -99,7 +107,8 @@ impl Action {
| Self::TagArtistPropertyUnset(_, _)
| Self::InitComplete
| Self::Save
| Self::ErrorInfo(_, _) => None,
| Self::ErrorInfo(_, _) => vec![],
Self::Multiple(actions) => actions.iter_mut().flat_map(|v| v.req_mut()).collect(),
}
}
}
@@ -215,6 +224,8 @@ pub enum Action {
TagArtistPropertySet(ArtistId, String, String),
TagArtistPropertyUnset(ArtistId, String),
Multiple(Vec<Self>),
InitComplete,
Save,
ErrorInfo(String, String),
@@ -471,6 +482,7 @@ const BYTE_PAUSE: u8 = 0b01_000_001;
const BYTE_STOP: u8 = 0b01_000_010;
const BYTE_NEXT_SONG: u8 = 0b01_000_100;
const BYTE_MULTIPLE: u8 = 0b01_010_100;
const BYTE_INIT_COMPLETE: u8 = 0b01_010_000;
const BYTE_SET_SONG_DURATION: u8 = 0b01_010_001;
const BYTE_SAVE: u8 = 0b01_010_010;
@@ -546,8 +558,7 @@ impl ToFromBytes for Req {
Ok(Self(ToFromBytes::from_bytes(s)?))
}
}
// impl ToFromBytes for Action {
impl Action {
impl ToFromBytes for Action {
fn to_bytes<T>(&self, s: &mut T) -> Result<(), std::io::Error>
where
T: Write,
@@ -753,6 +764,10 @@ impl Action {
i.to_bytes(s)?;
d.to_bytes(s)?;
}
Self::Multiple(actions) => {
s.write_all(&[BYTE_MULTIPLE])?;
actions.to_bytes(s)?;
}
Self::InitComplete => {
s.write_all(&[BYTE_INIT_COMPLETE])?;
}
@@ -880,6 +895,7 @@ impl Action {
}
},
BYTE_SET_SONG_DURATION => Self::SetSongDuration(from_bytes!(), from_bytes!()),
BYTE_MULTIPLE => Self::Multiple(from_bytes!()),
BYTE_INIT_COMPLETE => Self::InitComplete,
BYTE_SAVE => Self::Save,
BYTE_ERRORINFO => Self::ErrorInfo(from_bytes!(), from_bytes!()),