fix playback position being lost when moving

when moving a folder, loop, or any other
queue element containing the currently playing
song (unless the song was the first song in
the element), the player would reset the element
and jump to playing its first song again.
this is now fixed.
This commit is contained in:
Mark 2024-10-11 21:57:32 +02:00
parent 01e59249f5
commit 4bc3d0b147
5 changed files with 292 additions and 170 deletions

View File

@ -12,6 +12,7 @@ use musicdb_lib::{data::database::Database, server::Command};
use musicdb_mers::mers_lib::{ use musicdb_mers::mers_lib::{
data::{Data, Type}, data::{Data, Type},
errors::CheckError, errors::CheckError,
info::DisplayInfo,
}; };
use speedy2d::{color::Color, dimen::Vec2, shape::Rectangle, window::UserEventSender}; use speedy2d::{color::Color, dimen::Vec2, shape::Rectangle, window::UserEventSender};
@ -165,11 +166,11 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let v = Arc::clone(&self.updated_playing_status); let v = Arc::clone(&self.updated_playing_status);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `playback_resume` with argument of type `{a}` (must be `()`).").into()) Err(format!("Can't call `playback_resume` with argument of type `{}` (must be `()`).", a.with_info(i)).into())
} }
}, },
move |_, _| { move |_, _| {
@ -183,11 +184,11 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let v = Arc::clone(&self.updated_playing_status); let v = Arc::clone(&self.updated_playing_status);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `playback_pause` with argument of type `{a}` (must be `()`).").into()) Err(format!("Can't call `playback_pause` with argument of type `{}` (must be `()`).", a.with_info(i)).into())
} }
}, },
move |_, _| { move |_, _| {
@ -201,11 +202,11 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let v = Arc::clone(&self.updated_playing_status); let v = Arc::clone(&self.updated_playing_status);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a,i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `playback_stop` with argument of type `{a}` (must be `()`).").into()) Err(format!("Can't call `playback_stop` with argument of type `{}` (must be `()`).", a.with_info(i)).into())
} }
}, },
move |_, _| { move |_, _| {
@ -219,11 +220,11 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let v = Arc::clone(&self.updated_idle_status); let v = Arc::clone(&self.updated_idle_status);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `idle_start` with argument of type `{a}` (must be `()`).").into()) Err(format!("Can't call `idle_start` with argument of type `{}` (must be `()`).",a.with_info(i)).into())
} }
}, },
move |_, _| { move |_, _| {
@ -237,11 +238,11 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let v = Arc::clone(&self.updated_idle_status); let v = Arc::clone(&self.updated_idle_status);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a,i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `idle_stop` with argument of type `{a}` (must be `()`).").into()) Err(format!("Can't call `idle_stop` with argument of type `{}` (must be `()`).", a.with_info(i)).into())
} }
}, },
move |_, _| { move |_, _| {
@ -255,11 +256,11 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let v = Arc::clone(&self.updated_idle_status); let v = Arc::clone(&self.updated_idle_status);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a | { |a, i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `idle_prevent` with argument of type `{a}` (must be `()`).").into()) Err(format!("Can't call `idle_prevent` with argument of type `{}` (must be `()`).", a.with_info(i)).into())
} }
}, },
move |_, _| { move |_, _| {
@ -272,18 +273,18 @@ impl MersCfg {
.add_var("send_notification".to_owned(),{ .add_var("send_notification".to_owned(),{
let es = event_sender.clone(); let es = event_sender.clone();
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&musicdb_mers::mers_lib::data::tuple::TupleT(vec![ if a.is_included_in_single(&musicdb_mers::mers_lib::data::tuple::TupleT(vec![
musicdb_mers::mers_lib::data::Type::new(musicdb_mers::mers_lib::data::string::StringT), musicdb_mers::mers_lib::data::Type::new(musicdb_mers::mers_lib::data::string::StringT),
musicdb_mers::mers_lib::data::Type::new(musicdb_mers::mers_lib::data::string::StringT), musicdb_mers::mers_lib::data::Type::new(musicdb_mers::mers_lib::data::string::StringT),
musicdb_mers::mers_lib::data::Type::newm(vec![ musicdb_mers::mers_lib::data::Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::int::IntT), Arc::new(musicdb_mers::mers_lib::data::int::IntT(musicdb_mers::mers_lib::data::int::INT_MIN,musicdb_mers::mers_lib::data::int::INT_MAX)),
Arc::new(musicdb_mers::mers_lib::data::float::FloatT) Arc::new(musicdb_mers::mers_lib::data::float::FloatT)
]), ]),
])) { ])) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `send_notification` with argument of type `{a}` (must be `String`).").into()) Err(format!("Can't call `send_notification` with argument of type `{}` (must be `String`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -335,7 +336,7 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let update = Arc::clone(&self.updated_idle_screen_cover_pos); let update = Arc::clone(&self.updated_idle_screen_cover_pos);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in(&musicdb_mers::mers_lib::data::Type::newm(vec![ if a.is_included_in(&musicdb_mers::mers_lib::data::Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])), Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])),
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![ Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![
@ -347,7 +348,7 @@ impl MersCfg {
])) { ])) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `set_idle_screen_cover_pos` with argument of type `{a}` (must be `()` or `(Float, Float, Float, Float)`).").into()) Err(format!("Can't call `set_idle_screen_cover_pos` with argument of type `{}` (must be `()` or `(Float, Float, Float, Float)`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -365,7 +366,7 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let update = Arc::clone(&self.updated_idle_screen_artist_image_pos); let update = Arc::clone(&self.updated_idle_screen_artist_image_pos);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in(&musicdb_mers::mers_lib::data::Type::newm(vec![ if a.is_included_in(&musicdb_mers::mers_lib::data::Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])), Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])),
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![ Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![
@ -377,7 +378,7 @@ impl MersCfg {
])) { ])) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `set_idle_screen_artist_image_pos` with argument of type `{a}` (must be `()` or `(Float, Float, Float, Float)`).").into()) Err(format!("Can't call `set_idle_screen_artist_image_pos` with argument of type `{}` (must be `()` or `(Float, Float, Float, Float)`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -401,14 +402,14 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let update = Arc::clone(&self.updated_statusbar_text_format); let update = Arc::clone(&self.updated_statusbar_text_format);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) { if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])), Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])),
Arc::new(musicdb_mers::mers_lib::data::string::StringT), Arc::new(musicdb_mers::mers_lib::data::string::StringT),
])) ]))
} else { } else {
Err(format!("Can't call `set_statusbar_text_format` with argument of type `{a}` (must be `String`).").into()) Err(format!("Can't call `set_statusbar_text_format` with argument of type `{}` (must be `String`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -429,14 +430,14 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let update = Arc::clone(&self.updated_idle_screen_top_text_format); let update = Arc::clone(&self.updated_idle_screen_top_text_format);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) { if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])), Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])),
Arc::new(musicdb_mers::mers_lib::data::string::StringT), Arc::new(musicdb_mers::mers_lib::data::string::StringT),
])) ]))
} else { } else {
Err(format!("Can't call `set_idle_screen_top_text_format` with argument of type `{a}` (must be `String`).").into()) Err(format!("Can't call `set_idle_screen_top_text_format` with argument of type `{}` (must be `String`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -456,14 +457,14 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let update = Arc::clone(&self.updated_idle_screen_side_text_1_format); let update = Arc::clone(&self.updated_idle_screen_side_text_1_format);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) { if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])), Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])),
Arc::new(musicdb_mers::mers_lib::data::string::StringT), Arc::new(musicdb_mers::mers_lib::data::string::StringT),
])) ]))
} else { } else {
Err(format!("Can't call `set_idle_screen_side_text_1_format` with argument of type `{a}` (must be `String`).").into()) Err(format!("Can't call `set_idle_screen_side_text_1_format` with argument of type `{}` (must be `String`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -483,14 +484,14 @@ impl MersCfg {
let es = event_sender.clone(); let es = event_sender.clone();
let update = Arc::clone(&self.updated_idle_screen_side_text_2_format); let update = Arc::clone(&self.updated_idle_screen_side_text_2_format);
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) { if a.is_included_in_single(&musicdb_mers::mers_lib::data::string::StringT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])), Arc::new(musicdb_mers::mers_lib::data::tuple::TupleT(vec![])),
Arc::new(musicdb_mers::mers_lib::data::string::StringT), Arc::new(musicdb_mers::mers_lib::data::string::StringT),
])) ]))
} else { } else {
Err(format!("Can't call `set_idle_screen_side_text_2_format` with argument of type `{a}` (must be `String`).").into()) Err(format!("Can't call `set_idle_screen_side_text_2_format` with argument of type `{}` (must be `String`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {
@ -691,18 +692,20 @@ impl MersCfg {
.compile(&mut i1, Default::default())?; .compile(&mut i1, Default::default())?;
let _ = compiled.check(&mut i3, None)?; let _ = compiled.check(&mut i3, None)?;
let out = compiled.run(&mut i2)?; let out = compiled.run(&mut i2)?;
Ok(self.load3(out)) Ok(self.load3(out, i2.display_info()))
} }
fn load3( fn load3(
&mut self, &mut self,
out: musicdb_mers::mers_lib::data::Data, out: musicdb_mers::mers_lib::data::Data,
i: DisplayInfo,
) -> Result<(), (String, Option<CheckError>)> { ) -> Result<(), (String, Option<CheckError>)> {
if let Some(obj) = out if let Some(obj) = out
.get() .get()
.as_any() .as_any()
.downcast_ref::<musicdb_mers::mers_lib::data::object::Object>() .downcast_ref::<musicdb_mers::mers_lib::data::object::Object>()
{ {
for (name, val) in obj.0.iter() { for (name, val) in obj.iter() {
let name = i.get_object_field_name(*name).to_string();
let name = name.as_str(); let name = name.as_str();
match name { match name {
"before_draw" => { "before_draw" => {
@ -750,7 +753,7 @@ fn gen_set_pos_func(
update: Arc<Updatable<Rectangle>>, update: Arc<Updatable<Rectangle>>,
) -> musicdb_mers::mers_lib::data::function::Function { ) -> musicdb_mers::mers_lib::data::function::Function {
musicdb_mers::mers_lib::data::function::Function::new_generic( musicdb_mers::mers_lib::data::function::Function::new_generic(
move |a| { move |a, i| {
if a.is_included_in(&musicdb_mers::mers_lib::data::Type::newm(vec![Arc::new( if a.is_included_in(&musicdb_mers::mers_lib::data::Type::newm(vec![Arc::new(
musicdb_mers::mers_lib::data::tuple::TupleT(vec![ musicdb_mers::mers_lib::data::tuple::TupleT(vec![
musicdb_mers::mers_lib::data::Type::new( musicdb_mers::mers_lib::data::Type::new(
@ -769,7 +772,7 @@ fn gen_set_pos_func(
)])) { )])) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Can't call `{name}` with argument of type `{a}` (must be `(Float, Float, Float, Float)`).").into()) Err(format!("Can't call `{name}` with argument of type `{}` (must be `(Float, Float, Float, Float)`).", a.with_info(i)).into())
} }
}, },
move |a, _| { move |a, _| {

View File

@ -552,12 +552,12 @@ impl Database {
} }
Command::QueueAdd(index, new_data) => { Command::QueueAdd(index, new_data) => {
if let Some(v) = self.queue.get_item_at_index_mut(&index, 0) { if let Some(v) = self.queue.get_item_at_index_mut(&index, 0) {
v.add_to_end(new_data); v.add_to_end(new_data, false);
} }
} }
Command::QueueInsert(index, pos, new_data) => { Command::QueueInsert(index, pos, new_data) => {
if let Some(v) = self.queue.get_item_at_index_mut(&index, 0) { if let Some(v) = self.queue.get_item_at_index_mut(&index, 0) {
v.insert(new_data, pos); v.insert(new_data, pos, false);
} }
} }
Command::QueueRemove(index) => { Command::QueueRemove(index) => {
@ -598,9 +598,9 @@ impl Database {
.queue .queue
.get_item_at_index_mut(&index_to[0..index_to.len() - 1], 0) .get_item_at_index_mut(&index_to[0..index_to.len() - 1], 0)
{ {
parent.insert(vec![elem], index_to[index_to.len() - 1]); parent.insert(vec![elem], index_to[index_to.len() - 1], true);
if was_current { if was_current {
self.queue.set_index_inner(&index_to, 0, vec![]); self.queue.set_index_inner(&index_to, 0, vec![], true);
} }
} }
} }
@ -619,10 +619,10 @@ impl Database {
parent_to[index_from.len() - 1] -= 1; parent_to[index_from.len() - 1] -= 1;
} }
if let Some(parent) = self.queue.get_item_at_index_mut(&parent_to, 0) { if let Some(parent) = self.queue.get_item_at_index_mut(&parent_to, 0) {
if let Some(i) = parent.add_to_end(vec![elem]) { if let Some(i) = parent.add_to_end(vec![elem], true) {
if was_current { if was_current {
parent_to.push(i); parent_to.push(i);
self.queue.set_index_inner(&parent_to, 0, vec![]); self.queue.set_index_inner(&parent_to, 0, vec![], true);
} }
} }
} }

View File

@ -34,10 +34,10 @@ impl Queue {
&mut self.content &mut self.content
} }
pub fn add_to_end(&mut self, v: Vec<Self>) -> Option<usize> { pub fn add_to_end(&mut self, v: Vec<Self>, skip_init: bool) -> Option<usize> {
match &mut self.content { match &mut self.content {
QueueContent::Song(_) => None, QueueContent::Song(_) => None,
QueueContent::Folder(folder) => folder.add_to_end(v), QueueContent::Folder(folder) => folder.add_to_end(v, skip_init),
QueueContent::Loop(..) => None, QueueContent::Loop(..) => None,
} }
} }
@ -56,10 +56,10 @@ impl Queue {
QueueContent::Loop(_, _, inner) => index[0] == 0 && inner.is_current(&index[1..]), QueueContent::Loop(_, _, inner) => index[0] == 0 && inner.is_current(&index[1..]),
} }
} }
pub fn insert(&mut self, v: Vec<Self>, index: usize) -> bool { pub fn insert(&mut self, v: Vec<Self>, index: usize, skip_init: bool) -> bool {
match &mut self.content { match &mut self.content {
QueueContent::Song(_) => false, QueueContent::Song(_) => false,
QueueContent::Folder(folder) => folder.insert(v, index), QueueContent::Folder(folder) => folder.insert(v, index, skip_init),
QueueContent::Loop(..) => false, QueueContent::Loop(..) => false,
} }
} }
@ -215,9 +215,15 @@ impl Queue {
pub fn set_index_db(db: &mut Database, index: &[usize]) { pub fn set_index_db(db: &mut Database, index: &[usize]) {
db.queue.reset_index(); db.queue.reset_index();
db.queue.set_index_inner(index, 0, vec![]); db.queue.set_index_inner(index, 0, vec![], false);
} }
pub fn set_index_inner(&mut self, index: &[usize], depth: usize, mut build_index: Vec<usize>) { pub fn set_index_inner(
&mut self,
index: &[usize],
depth: usize,
mut build_index: Vec<usize>,
keep_child_indices: bool,
) {
let i = if let Some(i) = index.get(depth) { let i = if let Some(i) = index.get(depth) {
*i *i
} else { } else {
@ -229,13 +235,17 @@ impl Queue {
QueueContent::Folder(folder) => { QueueContent::Folder(folder) => {
folder.index = i; folder.index = i;
if let Some(c) = folder.get_current_mut() { if let Some(c) = folder.get_current_mut() {
c.init(); if !keep_child_indices {
c.set_index_inner(index, depth + 1, build_index); c.init();
}
c.set_index_inner(index, depth + 1, build_index, keep_child_indices);
} }
} }
QueueContent::Loop(_, _, inner) => { QueueContent::Loop(_, _, inner) => {
inner.init(); if !keep_child_indices {
inner.set_index_inner(index, depth + 1, build_index) inner.init();
}
inner.set_index_inner(index, depth + 1, build_index, keep_child_indices)
} }
} }
} }
@ -347,11 +357,13 @@ impl QueueFolder {
index: 0, index: 0,
} }
} }
pub fn add_to_end(&mut self, v: Vec<Queue>) -> Option<usize> { pub fn add_to_end(&mut self, v: Vec<Queue>, skip_init: bool) -> Option<usize> {
let add_len = v.len(); let add_len = v.len();
let len = self.content.len(); let len = self.content.len();
for mut v in v.into_iter() { for mut v in v.into_iter() {
v.init(); if !skip_init {
v.init();
}
self.content.push(v); self.content.push(v);
} }
if let Some(order) = &mut self.order { if let Some(order) = &mut self.order {
@ -361,7 +373,7 @@ impl QueueFolder {
} }
Some(len) Some(len)
} }
pub fn insert(&mut self, v: Vec<Queue>, index: usize) -> bool { pub fn insert(&mut self, v: Vec<Queue>, index: usize, skip_init: bool) -> bool {
if index <= self.content.len() { if index <= self.content.len() {
if self.index >= index { if self.index >= index {
self.index += v.len(); self.index += v.len();
@ -377,7 +389,9 @@ impl QueueFolder {
vec.extend(end); vec.extend(end);
} }
let mapfunc = |mut v: Queue| { let mapfunc = |mut v: Queue| {
v.init(); if !skip_init {
v.init();
}
v v
}; };
if let Some(order) = &mut self.order { if let Some(order) = &mut self.order {

View File

@ -6,5 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
mers_lib = { version = "0.9.1", features = ["ecolor-term"] } mers_lib = { version = "0.9.6", features = ["ecolor-term"] }
musicdb-lib = { version = "0.1.0", path = "../musicdb-lib" } musicdb-lib = { version = "0.1.0", path = "../musicdb-lib" }

View File

@ -6,7 +6,8 @@ use std::{
pub use mers_lib; pub use mers_lib;
use mers_lib::{ use mers_lib::{
data::{self, function::Function, Data, MersData, MersType, Type}, data::{self, function::Function, object::ObjectFieldsMap, Data, MersData, MersType, Type},
info::DisplayInfo,
prelude_extend_config::Config, prelude_extend_config::Config,
}; };
use musicdb_lib::{ use musicdb_lib::{
@ -157,7 +158,7 @@ pub fn add(
cfg = cfg.add_var( cfg = cfg.add_var(
format!("handle_event_{name}"), format!("handle_event_{name}"),
Function::new_generic( Function::new_generic(
move |a| { move |a, i| {
if a.types.iter().all(|a| { if a.types.iter().all(|a| {
Type::newm(vec![Arc::clone(a)]).is_zero_tuple() Type::newm(vec![Arc::clone(a)]).is_zero_tuple()
|| a.as_any() || a.as_any()
@ -166,7 +167,10 @@ pub fn add(
}) { }) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
Err(format!("Handler function must be `{in_type} -> ()`").into()) Err(
format!("Handler function must be `{} -> ()`", in_type.with_info(i))
.into(),
)
} }
}, },
move |a, _| { move |a, _| {
@ -180,7 +184,7 @@ pub fn add(
cfg.add_var( cfg.add_var(
"send_server_notification".to_owned(), "send_server_notification".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in_single(&data::string::StringT) { if a.is_included_in_single(&data::string::StringT) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -207,7 +211,7 @@ pub fn add(
.add_var( .add_var(
"resume".to_owned(), "resume".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -226,7 +230,7 @@ pub fn add(
.add_var( .add_var(
"pause".to_owned(), "pause".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -245,7 +249,7 @@ pub fn add(
.add_var( .add_var(
"stop".to_owned(), "stop".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -264,7 +268,7 @@ pub fn add(
.add_var( .add_var(
"next_song".to_owned(), "next_song".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -283,7 +287,7 @@ pub fn add(
.add_var( .add_var(
"get_playing".to_owned(), "get_playing".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(data::bool::bool_type()) Ok(data::bool::bool_type())
} else { } else {
@ -299,7 +303,7 @@ pub fn add(
.add_var( .add_var(
"queue_get_current_song".to_owned(), "queue_get_current_song".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(MusicDbIdT), Arc::new(MusicDbIdT),
@ -323,7 +327,7 @@ pub fn add(
.add_var( .add_var(
"queue_get_next_song".to_owned(), "queue_get_next_song".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(MusicDbIdT), Arc::new(MusicDbIdT),
@ -347,22 +351,22 @@ pub fn add(
.add_var( .add_var(
"queue_get_elem".to_owned(), "queue_get_elem".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&mers_lib::program::configs::with_list::ListT( if a.is_included_in_single(&mers_lib::program::configs::with_list::ListT(
Type::new(data::int::IntT), Type::new(data::int::IntT(data::int::INT_MIN, data::int::INT_MAX)),
)) { )) {
Ok(gen_queue_elem_type_or_empty_tuple()) Ok(gen_queue_elem_type_or_empty_tuple(i.display_info()))
} else { } else {
Err(format!("Function argument must be `List<Int>`.").into()) Err(format!("Function argument must be `List<Int>`.").into())
} }
}, },
{ {
let db = Arc::clone(db); let db = Arc::clone(db);
move |a, _| { move |a, i| {
let a = int_list_to_usize_vec(&a); let a = int_list_to_usize_vec(&a);
Ok( Ok(
if let Some(elem) = db.lock().unwrap().queue.get_item_at_index(&a, 0) { if let Some(elem) = db.lock().unwrap().queue.get_item_at_index(&a, 0) {
gen_queue_elem(elem) gen_queue_elem(elem, i.display_info())
} else { } else {
Data::empty_tuple() Data::empty_tuple()
}, },
@ -374,9 +378,9 @@ pub fn add(
.add_var( .add_var(
"queue_goto".to_owned(), "queue_goto".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in_single(&mers_lib::program::configs::with_list::ListT( if a.is_included_in_single(&mers_lib::program::configs::with_list::ListT(
Type::new(data::int::IntT), Type::new(data::int::IntT(data::int::INT_MIN, data::int::INT_MAX)),
)) { )) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -395,7 +399,7 @@ pub fn add(
.add_var( .add_var(
"queue_clear".to_owned(), "queue_clear".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in(&Type::empty_tuple()) { if a.is_included_in(&Type::empty_tuple()) {
Ok(Type::empty_tuple()) Ok(Type::empty_tuple())
} else { } else {
@ -533,10 +537,10 @@ pub fn add(
.add_var( .add_var(
"all_songs".to_owned(), "all_songs".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, i| {
if a.is_zero_tuple() { if a.is_zero_tuple() {
Ok(Type::new(mers_lib::program::configs::with_list::ListT( Ok(Type::new(mers_lib::program::configs::with_list::ListT(
Type::new(gen_song_type()), Type::new(gen_song_type(i.display_info())),
))) )))
} else { } else {
Err(format!("Function argument must be `()`.").into()) Err(format!("Function argument must be `()`.").into())
@ -544,13 +548,13 @@ pub fn add(
}, },
{ {
let db = Arc::clone(db); let db = Arc::clone(db);
move |_, _| { move |_, i| {
Ok(Data::new(mers_lib::program::configs::with_list::List( Ok(Data::new(mers_lib::program::configs::with_list::List(
db.lock() db.lock()
.unwrap() .unwrap()
.songs() .songs()
.values() .values()
.map(|s| Arc::new(RwLock::new(gen_song(s)))) .map(|s| Arc::new(RwLock::new(gen_song(s, i.display_info()))))
.collect(), .collect(),
))) )))
} }
@ -560,10 +564,10 @@ pub fn add(
.add_var( .add_var(
"get_song".to_owned(), "get_song".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&MusicDbIdT) { if a.is_included_in_single(&MusicDbIdT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(gen_song_type()), Arc::new(gen_song_type(i.display_info())),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
])) ]))
} else { } else {
@ -572,10 +576,10 @@ pub fn add(
}, },
{ {
let db = Arc::clone(db); let db = Arc::clone(db);
move |a, _| { move |a, i| {
let id = a.get().as_any().downcast_ref::<MusicDbId>().unwrap().0; let id = a.get().as_any().downcast_ref::<MusicDbId>().unwrap().0;
Ok(match db.lock().unwrap().get_song(&id) { Ok(match db.lock().unwrap().get_song(&id) {
Some(song) => gen_song(song), Some(song) => gen_song(song, i.display_info()),
None => Data::empty_tuple(), None => Data::empty_tuple(),
}) })
} }
@ -585,10 +589,10 @@ pub fn add(
.add_var( .add_var(
"get_album".to_owned(), "get_album".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&MusicDbIdT) { if a.is_included_in_single(&MusicDbIdT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(gen_album_type()), Arc::new(gen_album_type(i.display_info())),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
])) ]))
} else { } else {
@ -597,10 +601,10 @@ pub fn add(
}, },
{ {
let db = Arc::clone(db); let db = Arc::clone(db);
move |a, _| { move |a, i| {
let id = a.get().as_any().downcast_ref::<MusicDbId>().unwrap().0; let id = a.get().as_any().downcast_ref::<MusicDbId>().unwrap().0;
Ok(match db.lock().unwrap().albums().get(&id) { Ok(match db.lock().unwrap().albums().get(&id) {
Some(album) => gen_album(album), Some(album) => gen_album(album, i.display_info()),
None => Data::empty_tuple(), None => Data::empty_tuple(),
}) })
} }
@ -610,10 +614,10 @@ pub fn add(
.add_var( .add_var(
"get_artist".to_owned(), "get_artist".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, i| {
if a.is_included_in_single(&MusicDbIdT) { if a.is_included_in_single(&MusicDbIdT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(gen_artist_type()), Arc::new(gen_artist_type(i.display_info())),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
])) ]))
} else { } else {
@ -622,10 +626,10 @@ pub fn add(
}, },
{ {
let db = Arc::clone(db); let db = Arc::clone(db);
move |a, _| { move |a, i| {
let id = a.get().as_any().downcast_ref::<MusicDbId>().unwrap().0; let id = a.get().as_any().downcast_ref::<MusicDbId>().unwrap().0;
Ok(match db.lock().unwrap().artists().get(&id) { Ok(match db.lock().unwrap().artists().get(&id) {
Some(artist) => gen_artist(artist), Some(artist) => gen_artist(artist, i.display_info()),
None => Data::empty_tuple(), None => Data::empty_tuple(),
}) })
} }
@ -635,7 +639,7 @@ pub fn add(
.add_var( .add_var(
"get_song_tags".to_owned(), "get_song_tags".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in_single(&MusicDbIdT) { if a.is_included_in_single(&MusicDbIdT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(mers_lib::program::configs::with_list::ListT(Type::new( Arc::new(mers_lib::program::configs::with_list::ListT(Type::new(
@ -672,7 +676,7 @@ pub fn add(
.add_var( .add_var(
"get_album_tags".to_owned(), "get_album_tags".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in_single(&MusicDbIdT) { if a.is_included_in_single(&MusicDbIdT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(mers_lib::program::configs::with_list::ListT(Type::new( Arc::new(mers_lib::program::configs::with_list::ListT(Type::new(
@ -710,7 +714,7 @@ pub fn add(
.add_var( .add_var(
"get_artist_tags".to_owned(), "get_artist_tags".to_owned(),
Function::new_generic( Function::new_generic(
|a| { |a, _| {
if a.is_included_in_single(&MusicDbIdT) { if a.is_included_in_single(&MusicDbIdT) {
Ok(Type::newm(vec![ Ok(Type::newm(vec![
Arc::new(mers_lib::program::configs::with_list::ListT(Type::new( Arc::new(mers_lib::program::configs::with_list::ListT(Type::new(
@ -747,20 +751,29 @@ pub fn add(
) )
} }
fn gen_song_type() -> data::object::ObjectT { fn gen_song_type(i: DisplayInfo) -> data::object::ObjectT {
data::object::ObjectT(vec![ data::object::ObjectT::new(vec![
("id".to_owned(), Type::new(MusicDbIdT)),
("title".to_owned(), Type::new(data::string::StringT)),
( (
"album".to_owned(), i.object_fields.get_or_add_field("id"),
Type::new(MusicDbIdT),
),
(
i.object_fields.get_or_add_field("title"),
Type::new(data::string::StringT),
),
(
i.object_fields.get_or_add_field("album"),
Type::newm(vec![ Type::newm(vec![
Arc::new(MusicDbIdT), Arc::new(MusicDbIdT),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
]), ]),
), ),
("artist".to_owned(), Type::new(MusicDbIdT)),
( (
"cover".to_owned(), i.object_fields.get_or_add_field("artist"),
Type::new(MusicDbIdT),
),
(
i.object_fields.get_or_add_field("cover"),
Type::newm(vec![ Type::newm(vec![
Arc::new(MusicDbIdT), Arc::new(MusicDbIdT),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
@ -768,24 +781,30 @@ fn gen_song_type() -> data::object::ObjectT {
), ),
]) ])
} }
fn gen_song(song: &Song) -> Data { fn gen_song(song: &Song, i: DisplayInfo) -> Data {
Data::new(data::object::Object(vec![ Data::new(data::object::Object::new(vec![
("id".to_owned(), Data::new(MusicDbId(song.id))),
( (
"title".to_owned(), i.object_fields.get_or_add_field("id"),
Data::new(MusicDbId(song.id)),
),
(
i.object_fields.get_or_add_field("title"),
Data::new(data::string::String(song.title.clone())), Data::new(data::string::String(song.title.clone())),
), ),
( (
"album".to_owned(), i.object_fields.get_or_add_field("album"),
if let Some(album) = song.album { if let Some(album) = song.album {
Data::new(MusicDbId(album)) Data::new(MusicDbId(album))
} else { } else {
Data::empty_tuple() Data::empty_tuple()
}, },
), ),
("artist".to_owned(), Data::new(MusicDbId(song.artist))),
( (
"cover".to_owned(), i.object_fields.get_or_add_field("artist"),
Data::new(MusicDbId(song.artist)),
),
(
i.object_fields.get_or_add_field("cover"),
if let Some(cover) = song.cover { if let Some(cover) = song.cover {
Data::new(MusicDbId(cover)) Data::new(MusicDbId(cover))
} else { } else {
@ -794,36 +813,51 @@ fn gen_song(song: &Song) -> Data {
), ),
])) ]))
} }
fn gen_album_type() -> data::object::ObjectT { fn gen_album_type(i: DisplayInfo) -> data::object::ObjectT {
data::object::ObjectT(vec![ data::object::ObjectT::new(vec![
("id".to_owned(), Type::new(MusicDbIdT)),
("name".to_owned(), Type::new(data::string::StringT)),
("artist".to_owned(), Type::new(MusicDbIdT)),
( (
"cover".to_owned(), i.object_fields.get_or_add_field("id"),
Type::new(MusicDbIdT),
),
(
i.object_fields.get_or_add_field("name"),
Type::new(data::string::StringT),
),
(
i.object_fields.get_or_add_field("artist"),
Type::new(MusicDbIdT),
),
(
i.object_fields.get_or_add_field("cover"),
Type::newm(vec![ Type::newm(vec![
Arc::new(MusicDbIdT), Arc::new(MusicDbIdT),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
]), ]),
), ),
( (
"songs".to_owned(), i.object_fields.get_or_add_field("songs"),
Type::new(mers_lib::program::configs::with_list::ListT(Type::new( Type::new(mers_lib::program::configs::with_list::ListT(Type::new(
MusicDbIdT, MusicDbIdT,
))), ))),
), ),
]) ])
} }
fn gen_album(album: &Album) -> Data { fn gen_album(album: &Album, i: DisplayInfo) -> Data {
Data::new(data::object::Object(vec![ Data::new(data::object::Object::new(vec![
("id".to_owned(), Data::new(MusicDbId(album.id))),
( (
"name".to_owned(), i.object_fields.get_or_add_field("id"),
Data::new(MusicDbId(album.id)),
),
(
i.object_fields.get_or_add_field("name"),
Data::new(data::string::String(album.name.clone())), Data::new(data::string::String(album.name.clone())),
), ),
("artist".to_owned(), Data::new(MusicDbId(album.artist))),
( (
"cover".to_owned(), i.object_fields.get_or_add_field("artist"),
Data::new(MusicDbId(album.artist)),
),
(
i.object_fields.get_or_add_field("cover"),
if let Some(cover) = album.cover { if let Some(cover) = album.cover {
Data::new(MusicDbId(cover)) Data::new(MusicDbId(cover))
} else { } else {
@ -831,7 +865,7 @@ fn gen_album(album: &Album) -> Data {
}, },
), ),
( (
"songs".to_owned(), i.object_fields.get_or_add_field("songs"),
Data::new(mers_lib::program::configs::with_list::List( Data::new(mers_lib::program::configs::with_list::List(
album album
.songs .songs
@ -842,40 +876,49 @@ fn gen_album(album: &Album) -> Data {
), ),
])) ]))
} }
fn gen_artist_type() -> data::object::ObjectT { fn gen_artist_type(i: DisplayInfo) -> data::object::ObjectT {
data::object::ObjectT(vec![ data::object::ObjectT::new(vec![
("id".to_owned(), Type::new(MusicDbIdT)),
("name".to_owned(), Type::new(data::string::StringT)),
( (
"cover".to_owned(), i.object_fields.get_or_add_field("id"),
Type::new(MusicDbIdT),
),
(
i.object_fields.get_or_add_field("name"),
Type::new(data::string::StringT),
),
(
i.object_fields.get_or_add_field("cover"),
Type::newm(vec![ Type::newm(vec![
Arc::new(MusicDbIdT), Arc::new(MusicDbIdT),
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
]), ]),
), ),
( (
"albums".to_owned(), i.object_fields.get_or_add_field("albums"),
Type::new(mers_lib::program::configs::with_list::ListT(Type::new( Type::new(mers_lib::program::configs::with_list::ListT(Type::new(
MusicDbIdT, MusicDbIdT,
))), ))),
), ),
( (
"singles".to_owned(), i.object_fields.get_or_add_field("singles"),
Type::new(mers_lib::program::configs::with_list::ListT(Type::new( Type::new(mers_lib::program::configs::with_list::ListT(Type::new(
MusicDbIdT, MusicDbIdT,
))), ))),
), ),
]) ])
} }
fn gen_artist(artist: &Artist) -> Data { fn gen_artist(artist: &Artist, i: DisplayInfo) -> Data {
Data::new(data::object::Object(vec![ Data::new(data::object::Object::new(vec![
("id".to_owned(), Data::new(MusicDbId(artist.id))),
( (
"name".to_owned(), i.object_fields.get_or_add_field("id"),
Data::new(MusicDbId(artist.id)),
),
(
i.object_fields.get_or_add_field("name"),
Data::new(data::string::String(artist.name.clone())), Data::new(data::string::String(artist.name.clone())),
), ),
( (
"cover".to_owned(), i.object_fields.get_or_add_field("cover"),
if let Some(cover) = artist.cover { if let Some(cover) = artist.cover {
Data::new(MusicDbId(cover)) Data::new(MusicDbId(cover))
} else { } else {
@ -883,7 +926,7 @@ fn gen_artist(artist: &Artist) -> Data {
}, },
), ),
( (
"albums".to_owned(), i.object_fields.get_or_add_field("albums"),
Data::new(mers_lib::program::configs::with_list::List( Data::new(mers_lib::program::configs::with_list::List(
artist artist
.albums .albums
@ -893,7 +936,7 @@ fn gen_artist(artist: &Artist) -> Data {
)), )),
), ),
( (
"singles".to_owned(), i.object_fields.get_or_add_field("singles"),
Data::new(mers_lib::program::configs::with_list::List( Data::new(mers_lib::program::configs::with_list::List(
artist artist
.singles .singles
@ -905,72 +948,120 @@ fn gen_artist(artist: &Artist) -> Data {
])) ]))
} }
fn gen_queue_elem_type_or_empty_tuple() -> Type { fn gen_queue_elem_type_or_empty_tuple(i: DisplayInfo) -> Type {
Type::newm(vec![ Type::newm(vec![
Arc::new(data::tuple::TupleT(vec![])), Arc::new(data::tuple::TupleT(vec![])),
Arc::new(data::object::ObjectT(vec![ Arc::new(data::object::ObjectT::new(vec![
("enabled".to_owned(), data::bool::bool_type()),
("song".to_owned(), Type::new(MusicDbIdT)),
])),
Arc::new(data::object::ObjectT(vec![
("enabled".to_owned(), data::bool::bool_type()),
( (
"loop".to_owned(), i.object_fields.get_or_add_field("enabled"),
Type::new(data::object::ObjectT(vec![ data::bool::bool_type(),
("total".to_owned(), Type::new(data::int::IntT)), ),
("done".to_owned(), Type::new(data::int::IntT)), (
i.object_fields.get_or_add_field("song"),
Type::new(MusicDbIdT),
),
])),
Arc::new(data::object::ObjectT::new(vec![
(
i.object_fields.get_or_add_field("enabled"),
data::bool::bool_type(),
),
(
i.object_fields.get_or_add_field("loop"),
Type::new(data::object::ObjectT::new(vec![
(
i.object_fields.get_or_add_field("total"),
Type::new(data::int::IntT(data::int::INT_MIN, data::int::INT_MAX)),
),
(
i.object_fields.get_or_add_field("done"),
Type::new(data::int::IntT(data::int::INT_MIN, data::int::INT_MAX)),
),
])), ])),
), ),
])), ])),
Arc::new(data::object::ObjectT(vec![ Arc::new(data::object::ObjectT::new(vec![
("enabled".to_owned(), data::bool::bool_type()),
("random".to_owned(), Type::empty_tuple()),
])),
Arc::new(data::object::ObjectT(vec![
("enabled".to_owned(), data::bool::bool_type()),
( (
"folder".to_owned(), i.object_fields.get_or_add_field("enabled"),
Type::new(data::object::ObjectT(vec![ data::bool::bool_type(),
("index".to_owned(), Type::new(data::int::IntT)), ),
("length".to_owned(), Type::new(data::int::IntT)), (
("name".to_owned(), Type::new(data::string::StringT)), i.object_fields.get_or_add_field("random"),
Type::empty_tuple(),
),
])),
Arc::new(data::object::ObjectT::new(vec![
(
i.object_fields.get_or_add_field("enabled"),
data::bool::bool_type(),
),
(
i.object_fields.get_or_add_field("folder"),
Type::new(data::object::ObjectT::new(vec![
(
i.object_fields.get_or_add_field("index"),
Type::new(data::int::IntT(data::int::INT_MIN, data::int::INT_MAX)),
),
(
i.object_fields.get_or_add_field("length"),
Type::new(data::int::IntT(data::int::INT_MIN, data::int::INT_MAX)),
),
(
i.object_fields.get_or_add_field("name"),
Type::new(data::string::StringT),
),
])), ])),
), ),
])), ])),
Arc::new(data::object::ObjectT(vec![ Arc::new(data::object::ObjectT::new(vec![
("enabled".to_owned(), data::bool::bool_type()), (
("shuffle".to_owned(), Type::empty_tuple()), i.object_fields.get_or_add_field("enabled"),
data::bool::bool_type(),
),
(
i.object_fields.get_or_add_field("shuffle"),
Type::empty_tuple(),
),
])), ])),
]) ])
} }
fn gen_queue_elem(queue_elem: &Queue) -> Data { fn gen_queue_elem(queue_elem: &Queue, i: DisplayInfo) -> Data {
Data::new(data::object::Object(vec![ Data::new(data::object::Object::new(vec![
( (
"enabled".to_owned(), i.object_fields.get_or_add_field("enabled"),
Data::new(data::bool::Bool(queue_elem.enabled())), Data::new(data::bool::Bool(queue_elem.enabled())),
), ),
match queue_elem.content() { match queue_elem.content() {
QueueContent::Song(id) => ("song".to_owned(), Data::new(MusicDbId(*id))), QueueContent::Song(id) => (
i.object_fields.get_or_add_field("song"),
Data::new(MusicDbId(*id)),
),
QueueContent::Loop(total, done, _inner) => ( QueueContent::Loop(total, done, _inner) => (
"loop".to_owned(), i.object_fields.get_or_add_field("loop"),
Data::new(data::object::Object(vec![ Data::new(data::object::Object::new(vec![
("total".to_owned(), Data::new(data::int::Int(*total as _))), (
("done".to_owned(), Data::new(data::int::Int(*done as _))), i.object_fields.get_or_add_field("total"),
Data::new(data::int::Int(*total as _)),
),
(
i.object_fields.get_or_add_field("done"),
Data::new(data::int::Int(*done as _)),
),
])), ])),
), ),
QueueContent::Folder(folder) => ( QueueContent::Folder(folder) => (
"folder".to_owned(), i.object_fields.get_or_add_field("folder"),
Data::new(data::object::Object(vec![ Data::new(data::object::Object::new(vec![
( (
"index".to_owned(), i.object_fields.get_or_add_field("index"),
Data::new(data::int::Int(folder.index as _)), Data::new(data::int::Int(folder.index as _)),
), ),
( (
"length".to_owned(), i.object_fields.get_or_add_field("length"),
Data::new(data::int::Int(folder.content.len() as _)), Data::new(data::int::Int(folder.content.len() as _)),
), ),
( (
"name".to_owned(), i.object_fields.get_or_add_field("name"),
Data::new(data::string::String(folder.name.clone())), Data::new(data::string::String(folder.name.clone())),
), ),
])), ])),
@ -1009,6 +1100,13 @@ impl MersData for MusicDbId {
fn as_type(&self) -> Type { fn as_type(&self) -> Type {
Type::new(MusicDbIdT) Type::new(MusicDbIdT)
} }
fn display(
&self,
_info: &mers_lib::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{}", self)
}
fn is_eq(&self, other: &dyn MersData) -> bool { fn is_eq(&self, other: &dyn MersData) -> bool {
if let Some(other) = other.as_any().downcast_ref::<Self>() { if let Some(other) = other.as_any().downcast_ref::<Self>() {
self.0 == other.0 self.0 == other.0
@ -1030,6 +1128,13 @@ impl MersData for MusicDbId {
} }
} }
impl MersType for MusicDbIdT { impl MersType for MusicDbIdT {
fn display(
&self,
_info: &mers_lib::info::DisplayInfo<'_>,
f: &mut std::fmt::Formatter,
) -> std::fmt::Result {
write!(f, "{}", self)
}
fn is_same_type_as(&self, other: &dyn MersType) -> bool { fn is_same_type_as(&self, other: &dyn MersType) -> bool {
other.as_any().is::<Self>() other.as_any().is::<Self>()
} }