Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
10824204
Commit
10824204
authored
Jan 06, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
queue: convert all functions to methods
parent
70652abf
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
439 additions
and
525 deletions
+439
-525
Playlist.cxx
src/Playlist.cxx
+27
-36
PlaylistControl.cxx
src/PlaylistControl.cxx
+19
-23
PlaylistEdit.cxx
src/PlaylistEdit.cxx
+46
-54
PlaylistPrint.cxx
src/PlaylistPrint.cxx
+4
-4
PlaylistSave.cxx
src/PlaylistSave.cxx
+2
-2
PlaylistState.cxx
src/PlaylistState.cxx
+6
-9
Queue.cxx
src/Queue.cxx
+162
-178
Queue.hxx
src/Queue.hxx
+110
-155
QueueCommands.cxx
src/QueueCommands.cxx
+1
-1
QueuePrint.cxx
src/QueuePrint.cxx
+13
-13
QueueSave.cxx
src/QueueSave.cxx
+5
-5
TestQueuePriority.cxx
test/TestQueuePriority.cxx
+44
-45
No files found.
src/Playlist.cxx
View file @
10824204
...
...
@@ -36,7 +36,7 @@ extern "C" {
void
playlist_increment_version_all
(
struct
playlist
*
playlist
)
{
queue_modify_all
(
&
playlist
->
queue
);
playlist
->
queue
.
ModifyAll
(
);
idle_add
(
IDLE_PLAYLIST
);
}
...
...
@@ -48,7 +48,7 @@ playlist_tag_changed(struct playlist *playlist)
assert
(
playlist
->
current
>=
0
);
queue_modify
(
&
playlist
->
queue
,
playlist
->
current
);
playlist
->
queue
.
ModifyAtOrder
(
playlist
->
current
);
idle_add
(
IDLE_PLAYLIST
);
}
...
...
@@ -61,12 +61,12 @@ playlist_queue_song_order(struct playlist *playlist, struct player_control *pc,
{
char
*
uri
;
assert
(
queue_valid_order
(
&
playlist
->
queue
,
order
));
assert
(
playlist
->
queue
.
IsValidOrder
(
order
));
playlist
->
queued
=
order
;
struct
song
*
song
=
song_dup_detached
(
queue_get_order
(
&
playlist
->
queue
,
order
));
song_dup_detached
(
playlist
->
queue
.
GetOrder
(
order
));
uri
=
song_get_uri
(
song
);
g_debug
(
"queue song %i:
\"
%s
\"
"
,
playlist
->
queued
,
uri
);
...
...
@@ -93,8 +93,7 @@ playlist_song_started(struct playlist *playlist, struct player_control *pc)
if
(
playlist
->
queue
.
consume
)
playlist_delete
(
playlist
,
pc
,
queue_order_to_position
(
&
playlist
->
queue
,
current
));
playlist
->
queue
.
OrderToPosition
(
current
));
idle_add
(
IDLE_PLAYER
);
}
...
...
@@ -105,7 +104,7 @@ playlist_get_queued_song(struct playlist *playlist)
if
(
!
playlist
->
playing
||
playlist
->
queued
<
0
)
return
NULL
;
return
queue_get_order
(
&
playlist
->
queue
,
playlist
->
queued
);
return
playlist
->
queue
.
GetOrder
(
playlist
->
queued
);
}
void
...
...
@@ -119,11 +118,11 @@ playlist_update_queued_song(struct playlist *playlist,
if
(
!
playlist
->
playing
)
return
;
assert
(
!
queue_is_empty
(
&
playlist
->
queue
));
assert
(
!
playlist
->
queue
.
IsEmpty
(
));
assert
((
playlist
->
queued
<
0
)
==
(
prev
==
NULL
));
next_order
=
playlist
->
current
>=
0
?
queue_next_order
(
&
playlist
->
queue
,
playlist
->
current
)
?
playlist
->
queue
.
GetNextOrder
(
playlist
->
current
)
:
0
;
if
(
next_order
==
0
&&
playlist
->
queue
.
random
&&
...
...
@@ -132,21 +131,19 @@ playlist_update_queued_song(struct playlist *playlist,
order each time the playlist is played
completely */
unsigned
current_position
=
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
);
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
queue_shuffle_order
(
&
playlist
->
queue
);
playlist
->
queue
.
ShuffleOrder
(
);
/* make sure that the playlist->current still points to
the current song, after the song order has been
shuffled */
playlist
->
current
=
queue_position_to_order
(
&
playlist
->
queue
,
current_position
);
playlist
->
queue
.
PositionToOrder
(
current_position
);
}
if
(
next_order
>=
0
)
next_song
=
queue_get_order
(
&
playlist
->
queue
,
next_order
);
next_song
=
playlist
->
queue
.
GetOrder
(
next_order
);
else
next_song
=
NULL
;
...
...
@@ -174,7 +171,7 @@ playlist_play_order(struct playlist *playlist, struct player_control *pc,
playlist
->
queued
=
-
1
;
struct
song
*
song
=
song_dup_detached
(
queue_get_order
(
&
playlist
->
queue
,
orderNum
));
song_dup_detached
(
playlist
->
queue
.
GetOrder
(
orderNum
));
uri
=
song_get_uri
(
song
);
g_debug
(
"play %i:
\"
%s
\"
"
,
orderNum
,
uri
);
...
...
@@ -247,7 +244,7 @@ playlist_resume_playback(struct playlist *playlist, struct player_control *pc)
if
((
playlist
->
stop_on_error
&&
error
!=
PLAYER_ERROR_NONE
)
||
error
==
PLAYER_ERROR_OUTPUT
||
playlist
->
error_count
>=
queue_length
(
&
playlist
->
queue
))
playlist
->
error_count
>=
playlist
->
queue
.
GetLength
(
))
/* too many errors, or critical error: stop
playback */
playlist_stop
(
playlist
,
pc
);
...
...
@@ -306,10 +303,9 @@ playlist_order(struct playlist *playlist)
{
if
(
playlist
->
current
>=
0
)
/* update playlist.current, order==position now */
playlist
->
current
=
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
);
playlist
->
current
=
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
queue_restore_order
(
&
playlist
->
queue
);
playlist
->
queue
.
RestoreOrder
(
);
}
void
...
...
@@ -362,20 +358,18 @@ playlist_set_random(struct playlist *playlist, struct player_control *pc,
int
current_position
=
playlist
->
playing
&&
playlist
->
current
>=
0
?
(
int
)
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
)
?
(
int
)
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
:
-
1
;
queue_shuffle_order
(
&
playlist
->
queue
);
playlist
->
queue
.
ShuffleOrder
(
);
if
(
current_position
>=
0
)
{
/* make sure the current song is the first in
the order list, so the whole rest of the
playlist is played after that */
unsigned
current_order
=
queue_position_to_order
(
&
playlist
->
queue
,
current_position
);
queue_swap_order
(
&
playlist
->
queue
,
0
,
current_order
);
playlist
->
queue
.
PositionToOrder
(
current_position
);
playlist
->
queue
.
SwapOrders
(
0
,
current_order
);
playlist
->
current
=
0
;
}
else
playlist
->
current
=
-
1
;
...
...
@@ -391,8 +385,7 @@ int
playlist_get_current_song
(
const
struct
playlist
*
playlist
)
{
if
(
playlist
->
current
>=
0
)
return
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
);
return
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
return
-
1
;
}
...
...
@@ -403,13 +396,11 @@ playlist_get_next_song(const struct playlist *playlist)
if
(
playlist
->
current
>=
0
)
{
if
(
playlist
->
queue
.
single
==
1
&&
playlist
->
queue
.
repeat
==
1
)
return
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
);
else
if
(
playlist
->
current
+
1
<
(
int
)
queue_length
(
&
playlist
->
queue
))
return
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
+
1
);
return
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
else
if
(
playlist
->
current
+
1
<
(
int
)
playlist
->
queue
.
GetLength
())
return
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
+
1
);
else
if
(
playlist
->
queue
.
repeat
==
1
)
return
queue_order_to_position
(
&
playlist
->
queue
,
0
);
return
playlist
->
queue
.
OrderToPosition
(
0
);
}
return
-
1
;
...
...
@@ -424,11 +415,11 @@ playlist_get_version(const struct playlist *playlist)
int
playlist_get_length
(
const
struct
playlist
*
playlist
)
{
return
queue_length
(
&
playlist
->
queue
);
return
playlist
->
queue
.
GetLength
(
);
}
unsigned
playlist_get_song_id
(
const
struct
playlist
*
playlist
,
unsigned
song
)
{
return
queue_position_to_id
(
&
playlist
->
queue
,
song
);
return
playlist
->
queue
.
PositionToId
(
song
);
}
src/PlaylistControl.cxx
View file @
10824204
...
...
@@ -50,16 +50,14 @@ playlist_stop(struct playlist *playlist, struct player_control *pc)
result in a new random order */
unsigned
current_position
=
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
);
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
queue_shuffle_order
(
&
playlist
->
queue
);
playlist
->
queue
.
ShuffleOrder
(
);
/* make sure that "current" stays valid, and the next
"play" command plays the same song again */
playlist
->
current
=
queue_position_to_order
(
&
playlist
->
queue
,
current_position
);
playlist
->
queue
.
PositionToOrder
(
current_position
);
}
}
...
...
@@ -74,7 +72,7 @@ playlist_play(struct playlist *playlist, struct player_control *pc,
if
(
song
==
-
1
)
{
/* play any song ("current" song, or the first song */
if
(
queue_is_empty
(
&
playlist
->
queue
))
if
(
playlist
->
queue
.
IsEmpty
(
))
return
PLAYLIST_RESULT_SUCCESS
;
if
(
playlist
->
playing
)
{
...
...
@@ -88,7 +86,7 @@ playlist_play(struct playlist *playlist, struct player_control *pc,
i
=
playlist
->
current
>=
0
?
playlist
->
current
:
0
;
}
else
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
song
))
}
else
if
(
!
playlist
->
queue
.
IsValidPosition
(
song
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
(
playlist
->
queue
.
random
)
{
...
...
@@ -97,15 +95,14 @@ playlist_play(struct playlist *playlist, struct player_control *pc,
would be equal to the order number in
no-random mode); convert it to a order
number, because random mode is enabled */
i
=
queue_position_to_order
(
&
playlist
->
queue
,
song
);
i
=
playlist
->
queue
.
PositionToOrder
(
song
);
if
(
!
playlist
->
playing
)
playlist
->
current
=
0
;
/* swap the new song with the previous "current" one,
so playback continues as planned */
queue_swap_order
(
&
playlist
->
queue
,
i
,
playlist
->
current
);
playlist
->
queue
.
SwapOrders
(
i
,
playlist
->
current
);
i
=
playlist
->
current
;
}
...
...
@@ -126,7 +123,7 @@ playlist_play_id(struct playlist *playlist, struct player_control *pc,
return
playlist_play
(
playlist
,
pc
,
id
);
}
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id
);
song
=
playlist
->
queue
.
IdToPosition
(
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
...
...
@@ -142,15 +139,15 @@ playlist_next(struct playlist *playlist, struct player_control *pc)
if
(
!
playlist
->
playing
)
return
;
assert
(
!
queue_is_empty
(
&
playlist
->
queue
));
assert
(
queue_valid_order
(
&
playlist
->
queue
,
playlist
->
current
));
assert
(
!
playlist
->
queue
.
IsEmpty
(
));
assert
(
playlist
->
queue
.
IsValidOrder
(
playlist
->
current
));
current
=
playlist
->
current
;
playlist
->
stop_on_error
=
false
;
/* determine the next song from the queue's order list */
next_order
=
queue_next_order
(
&
playlist
->
queue
,
playlist
->
current
);
next_order
=
playlist
->
queue
.
GetNextOrder
(
playlist
->
current
);
if
(
next_order
<
0
)
{
/* no song after this one: stop playback */
playlist_stop
(
playlist
,
pc
);
...
...
@@ -167,7 +164,7 @@ playlist_next(struct playlist *playlist, struct player_control *pc)
songs in a different than before */
assert
(
playlist
->
queue
.
repeat
);
queue_shuffle_order
(
&
playlist
->
queue
);
playlist
->
queue
.
ShuffleOrder
(
);
/* note that playlist->current and playlist->queued are
now invalid, but playlist_play_order() will
...
...
@@ -180,8 +177,7 @@ playlist_next(struct playlist *playlist, struct player_control *pc)
/* Consume mode removes each played songs. */
if
(
playlist
->
queue
.
consume
)
playlist_delete
(
playlist
,
pc
,
queue_order_to_position
(
&
playlist
->
queue
,
current
));
playlist
->
queue
.
OrderToPosition
(
current
));
}
void
...
...
@@ -190,7 +186,7 @@ playlist_previous(struct playlist *playlist, struct player_control *pc)
if
(
!
playlist
->
playing
)
return
;
assert
(
queue_length
(
&
playlist
->
queue
)
>
0
);
assert
(
playlist
->
queue
.
GetLength
(
)
>
0
);
if
(
playlist
->
current
>
0
)
{
/* play the preceding song */
...
...
@@ -199,7 +195,7 @@ playlist_previous(struct playlist *playlist, struct player_control *pc)
}
else
if
(
playlist
->
queue
.
repeat
)
{
/* play the last song in "repeat" mode */
playlist_play_order
(
playlist
,
pc
,
queue_length
(
&
playlist
->
queue
)
-
1
);
playlist
->
queue
.
GetLength
(
)
-
1
);
}
else
{
/* re-start playing the current song if it's
the first one */
...
...
@@ -215,13 +211,13 @@ playlist_seek_song(struct playlist *playlist, struct player_control *pc,
unsigned
i
;
bool
success
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
song
))
if
(
!
playlist
->
queue
.
IsValidPosition
(
song
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
if
(
playlist
->
queue
.
random
)
i
=
queue_position_to_order
(
&
playlist
->
queue
,
song
);
i
=
playlist
->
queue
.
PositionToOrder
(
song
);
else
i
=
song
;
...
...
@@ -240,7 +236,7 @@ playlist_seek_song(struct playlist *playlist, struct player_control *pc,
}
struct
song
*
the_song
=
song_dup_detached
(
queue_get_order
(
&
playlist
->
queue
,
i
));
song_dup_detached
(
playlist
->
queue
.
GetOrder
(
i
));
success
=
pc_seek
(
pc
,
the_song
,
seek_time
);
if
(
!
success
)
{
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
...
...
@@ -258,7 +254,7 @@ enum playlist_result
playlist_seek_song_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id
,
float
seek_time
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id
);
int
song
=
playlist
->
queue
.
IdToPosition
(
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
...
...
src/PlaylistEdit.cxx
View file @
10824204
...
...
@@ -40,7 +40,7 @@ extern "C" {
static
void
playlist_increment_version
(
struct
playlist
*
playlist
)
{
queue_increment_version
(
&
playlist
->
queue
);
playlist
->
queue
.
IncrementVersion
(
);
idle_add
(
IDLE_PLAYLIST
);
}
...
...
@@ -50,7 +50,7 @@ playlist_clear(struct playlist *playlist, struct player_control *pc)
{
playlist_stop
(
playlist
,
pc
);
queue_clear
(
&
playlist
->
queue
);
playlist
->
queue
.
Clear
(
);
playlist
->
current
=
-
1
;
...
...
@@ -75,12 +75,12 @@ playlist_append_song(struct playlist *playlist, struct player_control *pc,
const
struct
song
*
queued
;
unsigned
id
;
if
(
queue_is_full
(
&
playlist
->
queue
))
if
(
playlist
->
queue
.
IsFull
(
))
return
PLAYLIST_RESULT_TOO_LARGE
;
queued
=
playlist_get_queued_song
(
playlist
);
id
=
queue_append
(
&
playlist
->
queue
,
song
,
0
);
id
=
playlist
->
queue
.
Append
(
song
,
0
);
if
(
playlist
->
queue
.
random
)
{
/* shuffle the new song into the list of remaining
...
...
@@ -91,9 +91,9 @@ playlist_append_song(struct playlist *playlist, struct player_control *pc,
start
=
playlist
->
queued
+
1
;
else
start
=
playlist
->
current
+
1
;
if
(
start
<
queue_length
(
&
playlist
->
queue
))
queue_shuffle_order_last
(
&
playlist
->
queue
,
start
,
queue_length
(
&
playlist
->
queue
));
if
(
start
<
playlist
->
queue
.
GetLength
(
))
playlist
->
queue
.
ShuffleOrderLast
(
start
,
playlist
->
queue
.
GetLength
(
));
}
playlist_increment_version
(
playlist
);
...
...
@@ -140,23 +140,20 @@ playlist_swap_songs(struct playlist *playlist, struct player_control *pc,
{
const
struct
song
*
queued
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
song1
)
||
!
queue_valid_position
(
&
playlist
->
queue
,
song2
))
if
(
!
playlist
->
queue
.
IsValidPosition
(
song1
)
||
!
playlist
->
queue
.
IsValidPosition
(
song2
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
queue_swap
(
&
playlist
->
queue
,
song1
,
song2
);
playlist
->
queue
.
SwapPositions
(
song1
,
song2
);
if
(
playlist
->
queue
.
random
)
{
/* update the queue order, so that playlist->current
still points to the current song order */
queue_swap_order
(
&
playlist
->
queue
,
queue_position_to_order
(
&
playlist
->
queue
,
song1
),
queue_position_to_order
(
&
playlist
->
queue
,
song2
));
playlist
->
queue
.
SwapOrders
(
playlist
->
queue
.
PositionToOrder
(
song1
),
playlist
->
queue
.
PositionToOrder
(
song2
));
}
else
{
/* correct the "current" song order */
...
...
@@ -177,8 +174,8 @@ enum playlist_result
playlist_swap_songs_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id1
,
unsigned
id2
)
{
int
song1
=
queue_id_to_position
(
&
playlist
->
queue
,
id1
);
int
song2
=
queue_id_to_position
(
&
playlist
->
queue
,
id2
);
int
song1
=
playlist
->
queue
.
IdToPosition
(
id1
);
int
song2
=
playlist
->
queue
.
IdToPosition
(
id2
);
if
(
song1
<
0
||
song2
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
...
...
@@ -191,11 +188,11 @@ playlist_set_priority(struct playlist *playlist, struct player_control *pc,
unsigned
start
,
unsigned
end
,
uint8_t
priority
)
{
if
(
start
>=
queue_length
(
&
playlist
->
queue
))
if
(
start
>=
playlist
->
queue
.
GetLength
(
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
(
end
>
queue_length
(
&
playlist
->
queue
))
end
=
queue_length
(
&
playlist
->
queue
);
if
(
end
>
playlist
->
queue
.
GetLength
(
))
end
=
playlist
->
queue
.
GetLength
(
);
if
(
start
>=
end
)
return
PLAYLIST_RESULT_SUCCESS
;
...
...
@@ -203,15 +200,14 @@ playlist_set_priority(struct playlist *playlist, struct player_control *pc,
/* remember "current" and "queued" */
int
current_position
=
playlist
->
current
>=
0
?
(
int
)
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
)
?
(
int
)
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
:
-
1
;
const
struct
song
*
queued
=
playlist_get_queued_song
(
playlist
);
/* apply the priority changes */
queue_set_priority_range
(
&
playlist
->
queue
,
start
,
end
,
priority
,
playlist
->
queue
.
SetPriorityRange
(
start
,
end
,
priority
,
playlist
->
current
);
playlist_increment_version
(
playlist
);
...
...
@@ -219,8 +215,7 @@ playlist_set_priority(struct playlist *playlist, struct player_control *pc,
/* restore "current" and choose a new "queued" */
if
(
current_position
>=
0
)
playlist
->
current
=
queue_position_to_order
(
&
playlist
->
queue
,
current_position
);
playlist
->
current
=
playlist
->
queue
.
PositionToOrder
(
current_position
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
...
...
@@ -231,7 +226,7 @@ enum playlist_result
playlist_set_priority_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song_id
,
uint8_t
priority
)
{
int
song_position
=
queue_id_to_position
(
&
playlist
->
queue
,
song_id
);
int
song_position
=
playlist
->
queue
.
IdToPosition
(
song_id
);
if
(
song_position
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
...
...
@@ -247,9 +242,9 @@ playlist_delete_internal(struct playlist *playlist, struct player_control *pc,
{
unsigned
songOrder
;
assert
(
song
<
queue_length
(
&
playlist
->
queue
));
assert
(
song
<
playlist
->
queue
.
GetLength
(
));
songOrder
=
queue_position_to_order
(
&
playlist
->
queue
,
song
);
songOrder
=
playlist
->
queue
.
PositionToOrder
(
song
);
if
(
playlist
->
playing
&&
playlist
->
current
==
(
int
)
songOrder
)
{
bool
paused
=
pc_get_state
(
pc
)
==
PLAYER_STATE_PAUSE
;
...
...
@@ -261,8 +256,7 @@ playlist_delete_internal(struct playlist *playlist, struct player_control *pc,
/* see which song is going to be played instead */
playlist
->
current
=
queue_next_order
(
&
playlist
->
queue
,
playlist
->
current
);
playlist
->
current
=
playlist
->
queue
.
GetNextOrder
(
playlist
->
current
);
if
(
playlist
->
current
==
(
int
)
songOrder
)
playlist
->
current
=
-
1
;
...
...
@@ -282,7 +276,7 @@ playlist_delete_internal(struct playlist *playlist, struct player_control *pc,
/* now do it: remove the song */
queue_delete
(
&
playlist
->
queue
,
song
);
playlist
->
queue
.
DeletePosition
(
song
);
/* update the "current" and "queued" variables */
...
...
@@ -297,7 +291,7 @@ playlist_delete(struct playlist *playlist, struct player_control *pc,
{
const
struct
song
*
queued
;
if
(
song
>=
queue_length
(
&
playlist
->
queue
))
if
(
song
>=
playlist
->
queue
.
GetLength
(
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
...
...
@@ -316,11 +310,11 @@ playlist_delete_range(struct playlist *playlist, struct player_control *pc,
{
const
struct
song
*
queued
;
if
(
start
>=
queue_length
(
&
playlist
->
queue
))
if
(
start
>=
playlist
->
queue
.
GetLength
(
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
(
end
>
queue_length
(
&
playlist
->
queue
))
end
=
queue_length
(
&
playlist
->
queue
);
if
(
end
>
playlist
->
queue
.
GetLength
(
))
end
=
playlist
->
queue
.
GetLength
(
);
if
(
start
>=
end
)
return
PLAYLIST_RESULT_SUCCESS
;
...
...
@@ -341,7 +335,7 @@ enum playlist_result
playlist_delete_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id
);
int
song
=
playlist
->
queue
.
IdToPosition
(
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
...
...
@@ -352,8 +346,8 @@ void
playlist_delete_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
struct
song
*
song
)
{
for
(
int
i
=
queue_length
(
&
playlist
->
queue
)
-
1
;
i
>=
0
;
--
i
)
if
(
song
==
queue_get
(
&
playlist
->
queue
,
i
))
for
(
int
i
=
playlist
->
queue
.
GetLength
(
)
-
1
;
i
>=
0
;
--
i
)
if
(
song
==
playlist
->
queue
.
Get
(
i
))
playlist_delete
(
playlist
,
pc
,
i
);
}
...
...
@@ -364,12 +358,12 @@ playlist_move_range(struct playlist *playlist, struct player_control *pc,
const
struct
song
*
queued
;
int
currentSong
;
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
start
)
||
!
queue_valid_position
(
&
playlist
->
queue
,
end
-
1
))
if
(
!
playlist
->
queue
.
IsValidPosition
(
start
)
||
!
playlist
->
queue
.
IsValidPosition
(
end
-
1
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
to
>=
0
&&
to
+
end
-
start
-
1
>=
queue_length
(
&
playlist
->
queue
))
||
(
to
<
0
&&
abs
(
to
)
>
(
int
)
queue_length
(
&
playlist
->
queue
)))
if
((
to
>=
0
&&
to
+
end
-
start
-
1
>=
playlist
->
queue
.
GetLength
(
))
||
(
to
<
0
&&
abs
(
to
)
>
(
int
)
playlist
->
queue
.
GetLength
(
)))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
int
)
start
==
to
)
...
...
@@ -383,19 +377,18 @@ playlist_move_range(struct playlist *playlist, struct player_control *pc,
* (-playlist.length == to) => move to position BEFORE current song
*/
currentSong
=
playlist
->
current
>=
0
?
(
int
)
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
)
?
(
int
)
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
:
-
1
;
if
(
to
<
0
&&
playlist
->
current
>=
0
)
{
if
(
start
<=
(
unsigned
)
currentSong
&&
(
unsigned
)
currentSong
<
end
)
/* no-op, can't be moved to offset of itself */
return
PLAYLIST_RESULT_SUCCESS
;
to
=
(
currentSong
+
abs
(
to
))
%
queue_length
(
&
playlist
->
queue
);
to
=
(
currentSong
+
abs
(
to
))
%
playlist
->
queue
.
GetLength
(
);
if
(
start
<
(
unsigned
)
to
)
to
--
;
}
queue_move_range
(
&
playlist
->
queue
,
start
,
end
,
to
);
playlist
->
queue
.
MoveRange
(
start
,
end
,
to
);
if
(
!
playlist
->
queue
.
random
)
{
/* update current/queued */
...
...
@@ -422,7 +415,7 @@ enum playlist_result
playlist_move_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id1
,
int
to
)
{
int
song
=
queue_id_to_position
(
&
playlist
->
queue
,
id1
);
int
song
=
playlist
->
queue
.
IdToPosition
(
id1
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
...
...
@@ -435,9 +428,9 @@ playlist_shuffle(struct playlist *playlist, struct player_control *pc,
{
const
struct
song
*
queued
;
if
(
end
>
queue_length
(
&
playlist
->
queue
))
if
(
end
>
playlist
->
queue
.
GetLength
(
))
/* correct the "end" offset */
end
=
queue_length
(
&
playlist
->
queue
);
end
=
playlist
->
queue
.
GetLength
(
);
if
((
start
+
1
)
>=
end
)
/* needs at least two entries. */
...
...
@@ -446,17 +439,16 @@ playlist_shuffle(struct playlist *playlist, struct player_control *pc,
queued
=
playlist_get_queued_song
(
playlist
);
if
(
playlist
->
playing
&&
playlist
->
current
>=
0
)
{
unsigned
current_position
;
current_position
=
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
);
current_position
=
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
if
(
current_position
>=
start
&&
current_position
<
end
)
{
/* put current playing song first */
queue_swap
(
&
playlist
->
queue
,
start
,
current_position
);
playlist
->
queue
.
SwapPositions
(
start
,
current_position
);
if
(
playlist
->
queue
.
random
)
{
playlist
->
current
=
queue_position_to_order
(
&
playlist
->
queue
,
start
);
playlist
->
queue
.
PositionToOrder
(
start
);
}
else
playlist
->
current
=
start
;
...
...
@@ -469,7 +461,7 @@ playlist_shuffle(struct playlist *playlist, struct player_control *pc,
playlist
->
current
=
-
1
;
}
queue_shuffle_range
(
&
playlist
->
queue
,
start
,
end
);
playlist
->
queue
.
ShuffleRange
(
start
,
end
);
playlist_increment_version
(
playlist
);
...
...
src/PlaylistPrint.cxx
View file @
10824204
...
...
@@ -41,7 +41,7 @@ playlist_print_uris(Client *client, const struct playlist *playlist)
{
const
struct
queue
*
queue
=
&
playlist
->
queue
;
queue_print_uris
(
client
,
queue
,
0
,
queue
_length
(
queue
));
queue_print_uris
(
client
,
queue
,
0
,
queue
->
GetLength
(
));
}
bool
...
...
@@ -50,9 +50,9 @@ playlist_print_info(Client *client, const struct playlist *playlist,
{
const
struct
queue
*
queue
=
&
playlist
->
queue
;
if
(
end
>
queue
_length
(
queue
))
if
(
end
>
queue
->
GetLength
(
))
/* correct the "end" offset */
end
=
queue
_length
(
queue
);
end
=
queue
->
GetLength
(
);
if
(
start
>
end
)
/* an invalid "start" offset is fatal */
...
...
@@ -69,7 +69,7 @@ playlist_print_id(Client *client, const struct playlist *playlist,
const
struct
queue
*
queue
=
&
playlist
->
queue
;
int
position
;
position
=
queue
_id_to_position
(
queue
,
id
);
position
=
queue
->
IdToPosition
(
id
);
if
(
position
<
0
)
/* no such song */
return
false
;
...
...
src/PlaylistSave.cxx
View file @
10824204
...
...
@@ -98,8 +98,8 @@ spl_save_queue(const char *name_utf8, const struct queue *queue)
if
(
file
==
NULL
)
return
PLAYLIST_RESULT_ERRNO
;
for
(
unsigned
i
=
0
;
i
<
queue
_length
(
queue
);
i
++
)
playlist_print_song
(
file
,
queue
_get
(
queue
,
i
));
for
(
unsigned
i
=
0
;
i
<
queue
->
GetLength
(
);
i
++
)
playlist_print_song
(
file
,
queue
->
Get
(
i
));
fclose
(
file
);
...
...
src/PlaylistState.cxx
View file @
10824204
...
...
@@ -74,8 +74,7 @@ playlist_state_save(FILE *fp, const struct playlist *playlist,
fputs
(
PLAYLIST_STATE_FILE_STATE_PLAY
"
\n
"
,
fp
);
}
fprintf
(
fp
,
PLAYLIST_STATE_FILE_CURRENT
"%i
\n
"
,
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
));
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
));
fprintf
(
fp
,
PLAYLIST_STATE_FILE_TIME
"%i
\n
"
,
(
int
)
player_status
.
elapsed_time
);
}
else
{
...
...
@@ -83,8 +82,7 @@ playlist_state_save(FILE *fp, const struct playlist *playlist,
if
(
playlist
->
current
>=
0
)
fprintf
(
fp
,
PLAYLIST_STATE_FILE_CURRENT
"%i
\n
"
,
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
));
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
));
}
fprintf
(
fp
,
PLAYLIST_STATE_FILE_RANDOM
"%i
\n
"
,
playlist
->
queue
.
random
);
...
...
@@ -123,7 +121,7 @@ playlist_state_load(TextFile &file, struct playlist *playlist)
}
}
queue_increment_version
(
&
playlist
->
queue
);
playlist
->
queue
.
IncrementVersion
(
);
}
bool
...
...
@@ -195,8 +193,8 @@ playlist_state_restore(const char *line, TextFile &file,
playlist_set_random
(
playlist
,
pc
,
random_mode
);
if
(
!
queue_is_empty
(
&
playlist
->
queue
))
{
if
(
!
queue_valid_position
(
&
playlist
->
queue
,
current
))
if
(
!
playlist
->
queue
.
IsEmpty
(
))
{
if
(
!
playlist
->
queue
.
IsValidPosition
(
current
))
current
=
0
;
if
(
state
==
PLAYER_STATE_PLAY
&&
...
...
@@ -239,8 +237,7 @@ playlist_state_get_hash(const struct playlist *playlist,
?
((
int
)
player_status
.
elapsed_time
<<
8
)
:
0
)
^
(
playlist
->
current
>=
0
?
(
queue_order_to_position
(
&
playlist
->
queue
,
playlist
->
current
)
<<
16
)
?
(
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
<<
16
)
:
0
)
^
((
int
)
pc_get_cross_fade
(
pc
)
<<
20
)
^
(
player_status
.
state
<<
24
)
^
...
...
src/Queue.cxx
View file @
10824204
...
...
@@ -23,6 +23,34 @@
#include <stdlib.h>
queue
::
queue
(
unsigned
_max_length
)
:
max_length
(
_max_length
),
length
(
0
),
version
(
1
),
items
(
g_new
(
struct
queue_item
,
max_length
)),
order
((
unsigned
*
)
g_malloc
(
sizeof
(
order
[
0
])
*
max_length
)),
id_to_position
((
int
*
)
g_malloc
(
sizeof
(
id_to_position
[
0
])
*
max_length
*
QUEUE_HASH_MULT
)),
repeat
(
false
),
single
(
false
),
consume
(
false
),
random
(
false
),
rand
(
g_rand_new
())
{
for
(
unsigned
i
=
0
;
i
<
max_length
*
QUEUE_HASH_MULT
;
++
i
)
id_to_position
[
i
]
=
-
1
;
}
queue
::~
queue
()
{
Clear
();
g_free
(
items
);
g_free
(
order
);
g_free
(
id_to_position
);
g_rand_free
(
rand
);
}
/**
* Generate a non-existing id number.
*/
...
...
@@ -42,15 +70,15 @@ queue_generate_id(const struct queue *queue)
}
int
queue
_next_order
(
const
struct
queue
*
queue
,
unsigned
order
)
queue
::
GetNextOrder
(
unsigned
_order
)
const
{
assert
(
order
<
queue
->
length
);
assert
(
_order
<
length
);
if
(
queue
->
single
&&
queue
->
repeat
&&
!
queue
->
consume
)
return
order
;
else
if
(
order
+
1
<
queue
->
length
)
return
order
+
1
;
else
if
(
queue
->
repeat
&&
(
order
>
0
||
!
queue
->
consume
))
if
(
single
&&
repeat
&&
!
consume
)
return
_
order
;
else
if
(
_order
+
1
<
length
)
return
_
order
+
1
;
else
if
(
repeat
&&
(
_order
>
0
||
!
consume
))
/* restart at first song */
return
0
;
else
...
...
@@ -59,79 +87,77 @@ queue_next_order(const struct queue *queue, unsigned order)
}
void
queue
_increment_version
(
struct
queue
*
queue
)
queue
::
IncrementVersion
(
)
{
static
unsigned
long
max
=
((
uint32_t
)
1
<<
31
)
-
1
;
queue
->
version
++
;
version
++
;
if
(
queue
->
version
>=
max
)
{
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
i
++
)
queue
->
items
[
i
].
version
=
0
;
if
(
version
>=
max
)
{
for
(
unsigned
i
=
0
;
i
<
length
;
i
++
)
items
[
i
].
version
=
0
;
queue
->
version
=
1
;
version
=
1
;
}
}
void
queue
_modify
(
struct
queue
*
queue
,
unsigned
order
)
queue
::
ModifyAtOrder
(
unsigned
_
order
)
{
unsigned
position
;
assert
(
order
<
queue
->
length
);
assert
(
_order
<
length
);
position
=
queue
->
order
[
order
];
queue
->
items
[
position
].
version
=
queue
->
version
;
unsigned
position
=
order
[
_
order
];
items
[
position
].
version
=
version
;
queue_increment_version
(
queue
);
IncrementVersion
(
);
}
void
queue
_modify_all
(
struct
queue
*
queue
)
queue
::
ModifyAll
(
)
{
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
i
++
)
queue
->
items
[
i
].
version
=
queue
->
version
;
for
(
unsigned
i
=
0
;
i
<
length
;
i
++
)
items
[
i
].
version
=
version
;
queue_increment_version
(
queue
);
IncrementVersion
(
);
}
unsigned
queue
_append
(
struct
queue
*
queue
,
struct
song
*
song
,
uint8_t
priority
)
queue
::
Append
(
struct
song
*
song
,
uint8_t
priority
)
{
unsigned
id
=
queue_generate_id
(
queue
);
unsigned
id
=
queue_generate_id
(
this
);
assert
(
!
queue_is_full
(
queue
));
assert
(
!
IsFull
(
));
auto
&
item
=
queue
->
items
[
queue
->
length
];
auto
&
item
=
items
[
length
];
item
.
song
=
song_dup_detached
(
song
);
item
.
id
=
id
;
item
.
version
=
queue
->
version
;
item
.
version
=
version
;
item
.
priority
=
priority
;
queue
->
order
[
queue
->
length
]
=
queue
->
length
;
queue
->
id_to_position
[
id
]
=
queue
->
length
;
order
[
length
]
=
length
;
id_to_position
[
id
]
=
length
;
++
queue
->
length
;
++
length
;
return
id
;
}
void
queue
_swap
(
struct
queue
*
queue
,
unsigned
position1
,
unsigned
position2
)
queue
::
SwapPositions
(
unsigned
position1
,
unsigned
position2
)
{
struct
queue_item
tmp
;
unsigned
id1
=
queue
->
items
[
position1
].
id
;
unsigned
id2
=
queue
->
items
[
position2
].
id
;
unsigned
id1
=
items
[
position1
].
id
;
unsigned
id2
=
items
[
position2
].
id
;
tmp
=
queue
->
items
[
position1
];
queue
->
items
[
position1
]
=
queue
->
items
[
position2
];
queue
->
items
[
position2
]
=
tmp
;
tmp
=
items
[
position1
];
items
[
position1
]
=
items
[
position2
];
items
[
position2
]
=
tmp
;
queue
->
items
[
position1
].
version
=
queue
->
version
;
queue
->
items
[
position2
].
version
=
queue
->
version
;
items
[
position1
].
version
=
version
;
items
[
position2
].
version
=
version
;
queue
->
id_to_position
[
id1
]
=
position2
;
queue
->
id_to_position
[
id2
]
=
position1
;
id_to_position
[
id1
]
=
position2
;
id_to_position
[
id2
]
=
position1
;
}
static
void
...
...
@@ -145,79 +171,79 @@ queue_move_song_to(struct queue *queue, unsigned from, unsigned to)
}
void
queue
_move
(
struct
queue
*
queue
,
unsigned
from
,
unsigned
to
)
queue
::
MovePostion
(
unsigned
from
,
unsigned
to
)
{
struct
queue_item
item
=
queue
->
items
[
from
];
struct
queue_item
item
=
items
[
from
];
/* move songs to one less in from->to */
for
(
unsigned
i
=
from
;
i
<
to
;
i
++
)
queue_move_song_to
(
queue
,
i
+
1
,
i
);
queue_move_song_to
(
this
,
i
+
1
,
i
);
/* move songs to one more in to->from */
for
(
unsigned
i
=
from
;
i
>
to
;
i
--
)
queue_move_song_to
(
queue
,
i
-
1
,
i
);
queue_move_song_to
(
this
,
i
-
1
,
i
);
/* put song at _to_ */
queue
->
id_to_position
[
item
.
id
]
=
to
;
queue
->
items
[
to
]
=
item
;
queue
->
items
[
to
].
version
=
queue
->
version
;
id_to_position
[
item
.
id
]
=
to
;
items
[
to
]
=
item
;
items
[
to
].
version
=
version
;
/* now deal with order */
if
(
queue
->
random
)
{
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
i
++
)
{
if
(
queue
->
order
[
i
]
>
from
&&
queue
->
order
[
i
]
<=
to
)
queue
->
order
[
i
]
--
;
else
if
(
queue
->
order
[
i
]
<
from
&&
queue
->
order
[
i
]
>=
to
)
queue
->
order
[
i
]
++
;
else
if
(
from
==
queue
->
order
[
i
])
queue
->
order
[
i
]
=
to
;
if
(
random
)
{
for
(
unsigned
i
=
0
;
i
<
length
;
i
++
)
{
if
(
order
[
i
]
>
from
&&
order
[
i
]
<=
to
)
order
[
i
]
--
;
else
if
(
order
[
i
]
<
from
&&
order
[
i
]
>=
to
)
order
[
i
]
++
;
else
if
(
from
==
order
[
i
])
order
[
i
]
=
to
;
}
}
}
void
queue
_move_range
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
,
unsigned
to
)
queue
::
MoveRange
(
unsigned
start
,
unsigned
end
,
unsigned
to
)
{
struct
queue_item
items
[
end
-
start
];
struct
queue_item
tmp
[
end
-
start
];
// Copy the original block [start,end-1]
for
(
unsigned
i
=
start
;
i
<
end
;
i
++
)
items
[
i
-
start
]
=
queue
->
items
[
i
];
tmp
[
i
-
start
]
=
items
[
i
];
// If to > start, we need to move to-start items to start, starting from end
for
(
unsigned
i
=
end
;
i
<
end
+
to
-
start
;
i
++
)
queue_move_song_to
(
queue
,
i
,
start
+
i
-
end
);
queue_move_song_to
(
this
,
i
,
start
+
i
-
end
);
// If to < start, we need to move start-to items to newend (= end + to - start), starting from to
// This is the same as moving items from start-1 to to (decreasing), with start-1 going to end-1
// We have to iterate in this order to avoid writing over something we haven't yet moved
for
(
unsigned
i
=
start
-
1
;
i
>=
to
&&
i
!=
G_MAXUINT
;
i
--
)
queue_move_song_to
(
queue
,
i
,
i
+
end
-
start
);
queue_move_song_to
(
this
,
i
,
i
+
end
-
start
);
// Copy the original block back in, starting at to.
for
(
unsigned
i
=
start
;
i
<
end
;
i
++
)
{
queue
->
id_to_position
[
items
[
i
-
start
].
id
]
=
to
+
i
-
start
;
queue
->
items
[
to
+
i
-
start
]
=
items
[
i
-
start
];
queue
->
items
[
to
+
i
-
start
].
version
=
queue
->
version
;
id_to_position
[
tmp
[
i
-
start
].
id
]
=
to
+
i
-
start
;
items
[
to
+
i
-
start
]
=
tmp
[
i
-
start
];
items
[
to
+
i
-
start
].
version
=
version
;
}
if
(
queue
->
random
)
{
if
(
random
)
{
// Update the positions in the queue.
// Note that the ranges for these cases are the same as the ranges of
// the loops above.
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
i
++
)
{
if
(
queue
->
order
[
i
]
>=
end
&&
queue
->
order
[
i
]
<
to
+
end
-
start
)
queue
->
order
[
i
]
-=
end
-
start
;
else
if
(
queue
->
order
[
i
]
<
start
&&
queue
->
order
[
i
]
>=
to
)
queue
->
order
[
i
]
+=
end
-
start
;
else
if
(
start
<=
queue
->
order
[
i
]
&&
queue
->
order
[
i
]
<
end
)
queue
->
order
[
i
]
+=
to
-
start
;
for
(
unsigned
i
=
0
;
i
<
length
;
i
++
)
{
if
(
order
[
i
]
>=
end
&&
order
[
i
]
<
to
+
end
-
start
)
order
[
i
]
-=
end
-
start
;
else
if
(
order
[
i
]
<
start
&&
order
[
i
]
>=
to
)
order
[
i
]
+=
end
-
start
;
else
if
(
start
<=
order
[
i
]
&&
order
[
i
]
<
end
)
order
[
i
]
+=
to
-
start
;
}
}
}
...
...
@@ -232,8 +258,7 @@ queue_move_order(struct queue *queue, unsigned from_order, unsigned to_order)
assert
(
from_order
<
queue
->
length
);
assert
(
to_order
<=
queue
->
length
);
const
unsigned
from_position
=
queue_order_to_position
(
queue
,
from_order
);
const
unsigned
from_position
=
queue
->
OrderToPosition
(
from_order
);
if
(
from_order
<
to_order
)
{
for
(
unsigned
i
=
from_order
;
i
<
to_order
;
++
i
)
...
...
@@ -247,85 +272,54 @@ queue_move_order(struct queue *queue, unsigned from_order, unsigned to_order)
}
void
queue
_delete
(
struct
queue
*
queue
,
unsigned
position
)
queue
::
DeletePosition
(
unsigned
position
)
{
struct
song
*
song
;
unsigned
id
,
order
;
assert
(
position
<
length
);
assert
(
position
<
queue
->
length
);
song
=
queue_get
(
queue
,
position
);
struct
song
*
song
=
Get
(
position
);
assert
(
!
song_in_database
(
song
)
||
song_is_detached
(
song
));
song_free
(
song
);
id
=
queue_position_to_id
(
queue
,
position
);
order
=
queue_position_to_order
(
queue
,
position
);
const
unsigned
id
=
PositionToId
(
position
);
const
unsigned
_order
=
PositionToOrder
(
position
);
--
queue
->
length
;
--
length
;
/* release the song id */
queue
->
id_to_position
[
id
]
=
-
1
;
id_to_position
[
id
]
=
-
1
;
/* delete song from songs array */
for
(
unsigned
i
=
position
;
i
<
queue
->
length
;
i
++
)
queue_move_song_to
(
queue
,
i
+
1
,
i
);
for
(
unsigned
i
=
position
;
i
<
length
;
i
++
)
queue_move_song_to
(
this
,
i
+
1
,
i
);
/* delete the entry from the order array */
for
(
unsigned
i
=
order
;
i
<
queue
->
length
;
i
++
)
queue
->
order
[
i
]
=
queue
->
order
[
i
+
1
];
for
(
unsigned
i
=
_order
;
i
<
length
;
i
++
)
order
[
i
]
=
order
[
i
+
1
];
/* readjust values in the order array */
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
i
++
)
if
(
queue
->
order
[
i
]
>
position
)
--
queue
->
order
[
i
];
for
(
unsigned
i
=
0
;
i
<
length
;
i
++
)
if
(
order
[
i
]
>
position
)
--
order
[
i
];
}
void
queue
_clear
(
struct
queue
*
queue
)
queue
::
Clear
(
)
{
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
i
++
)
{
struct
queue_item
*
item
=
&
queue
->
items
[
i
];
for
(
unsigned
i
=
0
;
i
<
length
;
i
++
)
{
struct
queue_item
*
item
=
&
items
[
i
];
assert
(
!
song_in_database
(
item
->
song
)
||
song_is_detached
(
item
->
song
));
song_free
(
item
->
song
);
queue
->
id_to_position
[
item
->
id
]
=
-
1
;
id_to_position
[
item
->
id
]
=
-
1
;
}
queue
->
length
=
0
;
}
queue
::
queue
(
unsigned
_max_length
)
:
max_length
(
_max_length
),
length
(
0
),
version
(
1
),
items
(
g_new
(
struct
queue_item
,
max_length
)),
order
((
unsigned
*
)
g_malloc
(
sizeof
(
order
[
0
])
*
max_length
)),
id_to_position
((
int
*
)
g_malloc
(
sizeof
(
id_to_position
[
0
])
*
max_length
*
QUEUE_HASH_MULT
)),
repeat
(
false
),
single
(
false
),
consume
(
false
),
random
(
false
),
rand
(
g_rand_new
())
{
for
(
unsigned
i
=
0
;
i
<
max_length
*
QUEUE_HASH_MULT
;
++
i
)
id_to_position
[
i
]
=
-
1
;
}
queue
::~
queue
()
{
queue_clear
(
this
);
g_free
(
items
);
g_free
(
order
);
g_free
(
id_to_position
);
g_rand_free
(
rand
);
length
=
0
;
}
static
const
struct
queue_item
*
...
...
@@ -390,8 +384,7 @@ queue_shuffle_order_range(struct queue *queue, unsigned start, unsigned end)
assert
(
end
<=
queue
->
length
);
for
(
unsigned
i
=
start
;
i
<
end
;
++
i
)
queue_swap_order
(
queue
,
i
,
g_rand_int_range
(
queue
->
rand
,
i
,
end
));
queue
->
SwapOrders
(
i
,
g_rand_int_range
(
queue
->
rand
,
i
,
end
));
}
/**
...
...
@@ -399,70 +392,66 @@ queue_shuffle_order_range(struct queue *queue, unsigned start, unsigned end)
* priority group.
*/
void
queue_shuffle_order_range_with_priority
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
)
queue
::
ShuffleOrderRangeWithPriority
(
unsigned
start
,
unsigned
end
)
{
assert
(
queue
!=
NULL
);
assert
(
queue
->
random
);
assert
(
random
);
assert
(
start
<=
end
);
assert
(
end
<=
queue
->
length
);
assert
(
end
<=
length
);
if
(
start
==
end
)
return
;
/* first group the range by priority */
queue_sort_order_by_priority
(
queue
,
start
,
end
);
queue_sort_order_by_priority
(
this
,
start
,
end
);
/* now shuffle each priority group */
unsigned
group_start
=
start
;
uint8_t
group_priority
=
queue_get_order_priority
(
queue
,
start
);
uint8_t
group_priority
=
queue_get_order_priority
(
this
,
start
);
for
(
unsigned
i
=
start
+
1
;
i
<
end
;
++
i
)
{
uint8_t
priority
=
queue_get_order_priority
(
queue
,
i
);
uint8_t
priority
=
queue_get_order_priority
(
this
,
i
);
assert
(
priority
<=
group_priority
);
if
(
priority
!=
group_priority
)
{
/* start of a new group - shuffle the one that
has just ended */
queue_shuffle_order_range
(
queue
,
group_start
,
i
);
queue_shuffle_order_range
(
this
,
group_start
,
i
);
group_start
=
i
;
group_priority
=
priority
;
}
}
/* shuffle the last group */
queue_shuffle_order_range
(
queue
,
group_start
,
end
);
queue_shuffle_order_range
(
this
,
group_start
,
end
);
}
void
queue
_shuffle_order
(
struct
queue
*
queue
)
queue
::
ShuffleOrder
(
)
{
queue_shuffle_order_range_with_priority
(
queue
,
0
,
queue
->
length
);
ShuffleOrderRangeWithPriority
(
0
,
length
);
}
static
void
queue_shuffle_order_first
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
)
{
queue_swap_order
(
queue
,
start
,
g_rand_int_range
(
queue
->
rand
,
start
,
end
));
queue
->
SwapOrders
(
start
,
g_rand_int_range
(
queue
->
rand
,
start
,
end
));
}
void
queue
_shuffle_order_last
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
)
queue
::
ShuffleOrderLast
(
unsigned
start
,
unsigned
end
)
{
queue_swap_order
(
queue
,
end
-
1
,
g_rand_int_range
(
queue
->
rand
,
start
,
end
));
SwapOrders
(
end
-
1
,
g_rand_int_range
(
rand
,
start
,
end
));
}
void
queue
_shuffle_range
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
)
queue
::
ShuffleRange
(
unsigned
start
,
unsigned
end
)
{
assert
(
start
<=
end
);
assert
(
end
<=
queue
->
length
);
assert
(
end
<=
length
);
for
(
unsigned
i
=
start
;
i
<
end
;
i
++
)
{
unsigned
ri
=
g_rand_int_range
(
queue
->
rand
,
i
,
end
);
queue_swap
(
queue
,
i
,
ri
);
unsigned
ri
=
g_rand_int_range
(
rand
,
i
,
end
);
SwapPositions
(
i
,
ri
);
}
}
...
...
@@ -479,7 +468,7 @@ queue_find_priority_order(const struct queue *queue, unsigned start_order,
assert
(
start_order
<=
queue
->
length
);
for
(
unsigned
order
=
start_order
;
order
<
queue
->
length
;
++
order
)
{
const
unsigned
position
=
queue
_order_to_position
(
queue
,
order
);
const
unsigned
position
=
queue
->
OrderToPosition
(
order
);
const
struct
queue_item
*
item
=
&
queue
->
items
[
position
];
if
(
item
->
priority
<=
priority
&&
order
!=
exclude_order
)
return
order
;
...
...
@@ -498,7 +487,7 @@ queue_count_same_priority(const struct queue *queue, unsigned start_order,
assert
(
start_order
<=
queue
->
length
);
for
(
unsigned
order
=
start_order
;
order
<
queue
->
length
;
++
order
)
{
const
unsigned
position
=
queue
_order_to_position
(
queue
,
order
);
const
unsigned
position
=
queue
->
OrderToPosition
(
order
);
const
struct
queue_item
*
item
=
&
queue
->
items
[
position
];
if
(
item
->
priority
!=
priority
)
return
order
-
start_order
;
...
...
@@ -508,39 +497,37 @@ queue_count_same_priority(const struct queue *queue, unsigned start_order,
}
bool
queue_set_priority
(
struct
queue
*
queue
,
unsigned
position
,
uint8_t
priority
,
int
after_order
)
queue
::
SetPriority
(
unsigned
position
,
uint8_t
priority
,
int
after_order
)
{
assert
(
queue
!=
NULL
);
assert
(
position
<
queue
->
length
);
assert
(
position
<
length
);
struct
queue_item
*
item
=
&
queue
->
items
[
position
];
struct
queue_item
*
item
=
&
items
[
position
];
uint8_t
old_priority
=
item
->
priority
;
if
(
old_priority
==
priority
)
return
false
;
item
->
version
=
queue
->
version
;
item
->
version
=
version
;
item
->
priority
=
priority
;
if
(
!
queue
->
random
)
if
(
!
random
)
/* don't reorder if not in random mode */
return
true
;
unsigned
order
=
queue_position_to_order
(
queue
,
position
);
unsigned
_order
=
PositionToOrder
(
position
);
if
(
after_order
>=
0
)
{
if
(
order
==
(
unsigned
)
after_order
)
if
(
_
order
==
(
unsigned
)
after_order
)
/* don't reorder the current song */
return
true
;
if
(
order
<
(
unsigned
)
after_order
)
{
if
(
_
order
<
(
unsigned
)
after_order
)
{
/* the specified song has been played already
- enqueue it only if its priority has just
become bigger than the current one's */
const
unsigned
after_position
=
queue_order_to_position
(
queue
,
after_order
);
OrderToPosition
(
after_order
);
const
struct
queue_item
*
after_item
=
&
queue
->
items
[
after_position
];
&
items
[
after_position
];
if
(
old_priority
>
after_item
->
priority
||
priority
<=
after_item
->
priority
)
/* priority hasn't become bigger */
...
...
@@ -552,44 +539,41 @@ queue_set_priority(struct queue *queue, unsigned position, uint8_t priority,
create a new priority group) */
const
unsigned
before_order
=
queue_find_priority_order
(
queue
,
after_order
+
1
,
priority
,
order
);
const
unsigned
new_order
=
before_order
>
order
queue_find_priority_order
(
this
,
after_order
+
1
,
priority
,
_
order
);
const
unsigned
new_order
=
before_order
>
_
order
?
before_order
-
1
:
before_order
;
queue_move_order
(
queue
,
order
,
new_order
);
queue_move_order
(
this
,
_
order
,
new_order
);
/* shuffle the song within that priority group */
const
unsigned
priority_count
=
queue_count_same_priority
(
queue
,
new_order
,
priority
);
queue_count_same_priority
(
this
,
new_order
,
priority
);
assert
(
priority_count
>=
1
);
queue_shuffle_order_first
(
queue
,
new_order
,
queue_shuffle_order_first
(
this
,
new_order
,
new_order
+
priority_count
);
return
true
;
}
bool
queue_set_priority_range
(
struct
queue
*
queue
,
unsigned
start_position
,
unsigned
end_position
,
queue
::
SetPriorityRange
(
unsigned
start_position
,
unsigned
end_position
,
uint8_t
priority
,
int
after_order
)
{
assert
(
queue
!=
NULL
);
assert
(
start_position
<=
end_position
);
assert
(
end_position
<=
queue
->
length
);
assert
(
end_position
<=
length
);
bool
modified
=
false
;
int
after_position
=
after_order
>=
0
?
(
int
)
queue_order_to_position
(
queue
,
after_order
)
?
(
int
)
OrderToPosition
(
after_order
)
:
-
1
;
for
(
unsigned
i
=
start_position
;
i
<
end_position
;
++
i
)
{
after_order
=
after_position
>=
0
?
(
int
)
queue_position_to_order
(
queue
,
after_position
)
?
(
int
)
PositionToOrder
(
after_position
)
:
-
1
;
modified
|=
queue_set_priority
(
queue
,
i
,
priority
,
after_order
);
modified
|=
SetPriority
(
i
,
priority
,
after_order
);
}
return
modified
;
...
...
src/Queue.hxx
View file @
10824204
...
...
@@ -20,10 +20,11 @@
#ifndef MPD_QUEUE_HXX
#define MPD_QUEUE_HXX
#include "gcc.h"
#include <glib.h>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
enum
{
...
...
@@ -110,169 +111,141 @@ struct queue {
queue
(
const
queue
&
other
)
=
delete
;
queue
&
operator
=
(
const
queue
&
other
)
=
delete
;
};
static
inline
unsigned
queue_length
(
const
struct
queue
*
queue
)
{
assert
(
queue
->
length
<=
queue
->
max_length
);
unsigned
GetLength
()
const
{
assert
(
length
<=
max_length
);
return
queue
->
length
;
}
return
length
;
}
/**
/**
* Determine if the queue is empty, i.e. there are no songs.
*/
static
inline
bool
queue_is_empty
(
const
struct
queue
*
queue
)
{
return
queue
->
length
==
0
;
}
bool
IsEmpty
()
const
{
return
length
==
0
;
}
/**
/**
* Determine if the maximum number of songs has been reached.
*/
static
inline
bool
queue_is_full
(
const
struct
queue
*
queue
)
{
assert
(
queue
->
length
<=
queue
->
max_length
);
bool
IsFull
()
const
{
assert
(
length
<=
max_length
);
return
queue
->
length
>=
queue
->
max_length
;
}
return
length
>=
max_length
;
}
/**
/**
* Is that a valid position number?
*/
static
inline
bool
queue_valid_position
(
const
struct
queue
*
queue
,
unsigned
position
)
{
return
position
<
queue
->
length
;
}
bool
IsValidPosition
(
unsigned
position
)
const
{
return
position
<
length
;
}
/**
/**
* Is that a valid order number?
*/
static
inline
bool
queue_valid_order
(
const
struct
queue
*
queue
,
unsigned
order
)
{
return
order
<
queue
->
length
;
}
static
inline
int
queue_id_to_position
(
const
struct
queue
*
queue
,
unsigned
id
)
{
if
(
id
>=
queue
->
max_length
*
QUEUE_HASH_MULT
)
bool
IsValidOrder
(
unsigned
_order
)
const
{
return
_order
<
length
;
}
int
IdToPosition
(
unsigned
id
)
const
{
if
(
id
>=
max_length
*
QUEUE_HASH_MULT
)
return
-
1
;
assert
(
queue
->
id_to_position
[
id
]
>=
-
1
);
assert
(
queue
->
id_to_position
[
id
]
<
(
int
)
queue
->
length
);
assert
(
id_to_position
[
id
]
>=
-
1
);
assert
(
id_to_position
[
id
]
<
(
int
)
length
);
return
queue
->
id_to_position
[
id
];
}
return
id_to_position
[
id
];
}
static
inline
int
queue_position_to_id
(
const
struct
queue
*
queue
,
unsigned
position
)
{
assert
(
position
<
queue
->
length
);
int
PositionToId
(
unsigned
position
)
const
{
assert
(
position
<
length
);
return
queue
->
items
[
position
].
id
;
}
return
items
[
position
].
id
;
}
static
inline
unsigned
queue_order_to_position
(
const
struct
queue
*
queue
,
unsigned
order
)
{
assert
(
order
<
queue
->
length
);
gcc_pure
unsigned
OrderToPosition
(
unsigned
_order
)
const
{
assert
(
_order
<
length
);
return
queue
->
order
[
order
];
}
return
order
[
_
order
];
}
static
inline
unsigned
queue_position_to_order
(
const
struct
queue
*
queue
,
unsigned
position
)
{
assert
(
position
<
queue
->
length
);
gcc_pure
unsigned
PositionToOrder
(
unsigned
position
)
const
{
assert
(
position
<
length
);
for
(
unsigned
i
=
0
;;
++
i
)
{
assert
(
i
<
queue
->
length
);
assert
(
i
<
length
);
if
(
queue
->
order
[
i
]
==
position
)
if
(
order
[
i
]
==
position
)
return
i
;
}
}
}
G_GNUC_PURE
static
inline
uint8_t
queue_get_priority_at_position
(
const
struct
queue
*
queue
,
unsigned
position
)
{
assert
(
position
<
queue
->
length
);
G_GNUC_PURE
uint8_t
GetPriorityAtPosition
(
unsigned
position
)
const
{
assert
(
position
<
length
);
return
queue
->
items
[
position
].
priority
;
}
return
items
[
position
].
priority
;
}
/**
/**
* Returns the song at the specified position.
*/
static
inline
struct
song
*
queue_get
(
const
struct
queue
*
queue
,
unsigned
position
)
{
assert
(
position
<
queue
->
length
);
struct
song
*
Get
(
unsigned
position
)
const
{
assert
(
position
<
length
);
return
queue
->
items
[
position
].
song
;
}
return
items
[
position
].
song
;
}
/**
/**
* Returns the song at the specified order number.
*/
static
inline
struct
song
*
queue_get_order
(
const
struct
queue
*
queue
,
unsigned
order
)
{
return
queue_get
(
queue
,
queue_order_to_position
(
queue
,
order
));
}
struct
song
*
GetOrder
(
unsigned
_order
)
const
{
return
Get
(
OrderToPosition
(
_order
));
}
/**
/**
* Is the song at the specified position newer than the specified
* version?
*/
static
inline
bool
queue_song_newer
(
const
struct
queue
*
queue
,
unsigned
position
,
uint32_t
version
)
{
assert
(
position
<
queue
->
length
);
bool
IsNewerAtPosition
(
unsigned
position
,
uint32_t
_version
)
const
{
assert
(
position
<
length
);
return
version
>
queue
->
version
||
queue
->
items
[
position
].
version
>=
version
||
queue
->
items
[
position
].
version
==
0
;
}
return
_version
>
version
||
items
[
position
].
version
>=
_
version
||
items
[
position
].
version
==
0
;
}
/**
/**
* Returns the order number following the specified one. This takes
* end of queue and "repeat" mode into account.
*
* @return the next order number, or -1 to stop playback
*/
int
queue_next_order
(
const
struct
queue
*
queue
,
unsigned
order
)
;
gcc_pure
int
GetNextOrder
(
unsigned
order
)
const
;
/**
/**
* Increments the queue's version number. This handles integer
* overflow well.
*/
void
queue_increment_version
(
struct
queue
*
queue
);
void
IncrementVersion
();
/**
/**
* Marks the specified song as "modified" and increments the version
* number.
*/
void
queue_modify
(
struct
queue
*
queue
,
unsigned
order
);
void
ModifyAtOrder
(
unsigned
order
);
/**
/**
* Marks all songs as "modified" and increments the version number.
*/
void
queue_modify_all
(
struct
queue
*
queue
);
void
ModifyAll
();
/**
/**
* Appends a song to the queue and returns its position. Prior to
* that, the caller must check if the queue is already full.
*
...
...
@@ -281,97 +254,79 @@ queue_modify_all(struct queue *queue);
*
* @param priority the priority of this new queue item
*/
unsigned
queue_append
(
struct
queue
*
queue
,
struct
song
*
song
,
uint8_t
priority
);
unsigned
Append
(
struct
song
*
song
,
uint8_t
priority
);
/**
/**
* Swaps two songs, addressed by their position.
*/
void
queue_swap
(
struct
queue
*
queue
,
unsigned
position1
,
unsigned
position2
);
void
SwapPositions
(
unsigned
position1
,
unsigned
position2
);
/**
/**
* Swaps two songs, addressed by their order number.
*/
static
inline
void
queue_swap_order
(
struct
queue
*
queue
,
unsigned
order1
,
unsigned
order2
)
{
unsigned
tmp
=
queue
->
order
[
order1
];
queue
->
order
[
order1
]
=
queue
->
order
[
order2
];
queue
->
order
[
order2
]
=
tmp
;
}
void
SwapOrders
(
unsigned
order1
,
unsigned
order2
)
{
unsigned
tmp
=
order
[
order1
];
order
[
order1
]
=
order
[
order2
];
order
[
order2
]
=
tmp
;
}
/**
/**
* Moves a song to a new position.
*/
void
queue_move
(
struct
queue
*
queue
,
unsigned
from
,
unsigned
to
);
void
MovePostion
(
unsigned
from
,
unsigned
to
);
/**
/**
* Moves a range of songs to a new position.
*/
void
queue_move_range
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
,
unsigned
to
);
void
MoveRange
(
unsigned
start
,
unsigned
end
,
unsigned
to
);
/**
/**
* Removes a song from the playlist.
*/
void
queue_delete
(
struct
queue
*
queue
,
unsigned
position
);
void
DeletePosition
(
unsigned
position
);
/**
/**
* Removes all songs from the playlist.
*/
void
queue_clear
(
struct
queue
*
queue
);
void
Clear
();
/**
/**
* Initializes the "order" array, and restores "normal" order.
*/
static
inline
void
queue_restore_order
(
struct
queue
*
queue
)
{
for
(
unsigned
i
=
0
;
i
<
queue
->
length
;
++
i
)
queue
->
order
[
i
]
=
i
;
}
void
RestoreOrder
()
{
for
(
unsigned
i
=
0
;
i
<
length
;
++
i
)
order
[
i
]
=
i
;
}
/**
/**
* Shuffle the order of items in the specified range, taking their
* priorities into account.
*/
void
queue_shuffle_order_range_with_priority
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
);
void
ShuffleOrderRangeWithPriority
(
unsigned
start
,
unsigned
end
);
/**
/**
* Shuffles the virtual order of songs, but does not move them
* physically. This is used in random mode.
*/
void
queue_shuffle_order
(
struct
queue
*
queue
);
void
ShuffleOrder
();
/**
/**
* Shuffles the virtual order of the last song in the specified
* (order) range. This is used in random mode after a song has been
* appended by queue_append().
*/
void
queue_shuffle_order_last
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
);
void
ShuffleOrderLast
(
unsigned
start
,
unsigned
end
);
/**
/**
* Shuffles a (position) range in the queue. The songs are physically
* shuffled, not by using the "order" mapping.
*/
void
queue_shuffle_range
(
struct
queue
*
queue
,
unsigned
start
,
unsigned
end
);
void
ShuffleRange
(
unsigned
start
,
unsigned
end
);
bool
queue_set_priority
(
struct
queue
*
queue
,
unsigned
position
,
uint8_t
priority
,
int
after_order
);
bool
SetPriority
(
unsigned
position
,
uint8_t
priority
,
int
after_order
);
bool
queue_set_priority_range
(
struct
queue
*
queue
,
unsigned
start_position
,
unsigned
end_position
,
bool
SetPriorityRange
(
unsigned
start_position
,
unsigned
end_position
,
uint8_t
priority
,
int
after_order
);
};
#endif
src/QueueCommands.cxx
View file @
10824204
...
...
@@ -171,7 +171,7 @@ enum command_return
handle_shuffle
(
G_GNUC_UNUSED
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
G_GNUC_UNUSED
char
*
argv
[])
{
unsigned
start
=
0
,
end
=
queue_length
(
&
client
->
playlist
.
queue
);
unsigned
start
=
0
,
end
=
client
->
playlist
.
queue
.
GetLength
(
);
if
(
argc
==
2
&&
!
check_range
(
client
,
&
start
,
&
end
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
...
...
src/QueuePrint.cxx
View file @
10824204
...
...
@@ -41,11 +41,11 @@ static void
queue_print_song_info
(
Client
*
client
,
const
struct
queue
*
queue
,
unsigned
position
)
{
song_print_info
(
client
,
queue
_get
(
queue
,
position
));
song_print_info
(
client
,
queue
->
Get
(
position
));
client_printf
(
client
,
"Pos: %u
\n
Id: %u
\n
"
,
position
,
queue
_position_to_id
(
queue
,
position
));
position
,
queue
->
PositionToId
(
position
));
uint8_t
priority
=
queue
_get_priority_at_position
(
queue
,
position
);
uint8_t
priority
=
queue
->
GetPriorityAtPosition
(
position
);
if
(
priority
!=
0
)
client_printf
(
client
,
"Prio: %u
\n
"
,
priority
);
}
...
...
@@ -55,7 +55,7 @@ queue_print_info(Client *client, const struct queue *queue,
unsigned
start
,
unsigned
end
)
{
assert
(
start
<=
end
);
assert
(
end
<=
queue
_length
(
queue
));
assert
(
end
<=
queue
->
GetLength
(
));
for
(
unsigned
i
=
start
;
i
<
end
;
++
i
)
queue_print_song_info
(
client
,
queue
,
i
);
...
...
@@ -66,11 +66,11 @@ queue_print_uris(Client *client, const struct queue *queue,
unsigned
start
,
unsigned
end
)
{
assert
(
start
<=
end
);
assert
(
end
<=
queue
_length
(
queue
));
assert
(
end
<=
queue
->
GetLength
(
));
for
(
unsigned
i
=
start
;
i
<
end
;
++
i
)
{
client_printf
(
client
,
"%i:"
,
i
);
song_print_uri
(
client
,
queue
_get
(
queue
,
i
));
song_print_uri
(
client
,
queue
->
Get
(
i
));
}
}
...
...
@@ -78,8 +78,8 @@ void
queue_print_changes_info
(
Client
*
client
,
const
struct
queue
*
queue
,
uint32_t
version
)
{
for
(
unsigned
i
=
0
;
i
<
queue
_length
(
queue
);
i
++
)
{
if
(
queue
_song_newer
(
queue
,
i
,
version
))
for
(
unsigned
i
=
0
;
i
<
queue
->
GetLength
(
);
i
++
)
{
if
(
queue
->
IsNewerAtPosition
(
i
,
version
))
queue_print_song_info
(
client
,
queue
,
i
);
}
}
...
...
@@ -88,18 +88,18 @@ void
queue_print_changes_position
(
Client
*
client
,
const
struct
queue
*
queue
,
uint32_t
version
)
{
for
(
unsigned
i
=
0
;
i
<
queue
_length
(
queue
);
i
++
)
if
(
queue
_song_newer
(
queue
,
i
,
version
))
for
(
unsigned
i
=
0
;
i
<
queue
->
GetLength
(
);
i
++
)
if
(
queue
->
IsNewerAtPosition
(
i
,
version
))
client_printf
(
client
,
"cpos: %i
\n
Id: %i
\n
"
,
i
,
queue
_position_to_id
(
queue
,
i
));
i
,
queue
->
PositionToId
(
i
));
}
void
queue_find
(
Client
*
client
,
const
struct
queue
*
queue
,
const
SongFilter
&
filter
)
{
for
(
unsigned
i
=
0
;
i
<
queue
_length
(
queue
);
i
++
)
{
const
struct
song
*
song
=
queue
_get
(
queue
,
i
);
for
(
unsigned
i
=
0
;
i
<
queue
->
GetLength
(
);
i
++
)
{
const
struct
song
*
song
=
queue
->
Get
(
i
);
if
(
filter
.
Match
(
*
song
))
queue_print_song_info
(
client
,
queue
,
i
);
...
...
src/QueueSave.cxx
View file @
10824204
...
...
@@ -61,19 +61,19 @@ queue_save_song(FILE *fp, int idx, const struct song *song)
void
queue_save
(
FILE
*
fp
,
const
struct
queue
*
queue
)
{
for
(
unsigned
i
=
0
;
i
<
queue
_length
(
queue
);
i
++
)
{
uint8_t
prio
=
queue
_get_priority_at_position
(
queue
,
i
);
for
(
unsigned
i
=
0
;
i
<
queue
->
GetLength
(
);
i
++
)
{
uint8_t
prio
=
queue
->
GetPriorityAtPosition
(
i
);
if
(
prio
!=
0
)
fprintf
(
fp
,
PRIO_LABEL
"%u
\n
"
,
prio
);
queue_save_song
(
fp
,
i
,
queue
_get
(
queue
,
i
));
queue_save_song
(
fp
,
i
,
queue
->
Get
(
i
));
}
}
void
queue_load_song
(
TextFile
&
file
,
const
char
*
line
,
queue
*
queue
)
{
if
(
queue
_is_full
(
queue
))
if
(
queue
->
IsFull
(
))
return
;
uint8_t
priority
=
0
;
...
...
@@ -123,7 +123,7 @@ queue_load_song(TextFile &file, const char *line, queue *queue)
}
}
queue
_append
(
queue
,
song
,
priority
);
queue
->
Append
(
song
,
priority
);
if
(
db
!=
nullptr
)
db
->
ReturnSong
(
song
);
...
...
test/TestQueuePriority.cxx
View file @
10824204
...
...
@@ -23,21 +23,21 @@ G_GNUC_UNUSED
static
void
dump_order
(
const
struct
queue
*
queue
)
{
g_printerr
(
"queue length=%u, order:
\n
"
,
queue
_length
(
queue
));
for
(
unsigned
i
=
0
;
i
<
queue
_length
(
queue
);
++
i
)
g_printerr
(
"queue length=%u, order:
\n
"
,
queue
->
GetLength
(
));
for
(
unsigned
i
=
0
;
i
<
queue
->
GetLength
(
);
++
i
)
g_printerr
(
" [%u] -> %u (prio=%u)
\n
"
,
i
,
queue
->
order
[
i
],
queue
->
items
[
queue
->
order
[
i
]].
priority
);
}
static
void
check_descending_priority
(
G_GNUC_UNUSED
const
struct
queue
*
queue
,
check_descending_priority
(
const
struct
queue
*
queue
,
unsigned
start_order
)
{
assert
(
start_order
<
queue
_length
(
queue
));
assert
(
start_order
<
queue
->
GetLength
(
));
uint8_t
last_priority
=
0xff
;
for
(
unsigned
order
=
start_order
;
order
<
queue
_length
(
queue
);
++
order
)
{
unsigned
position
=
queue
_order_to_position
(
queue
,
order
);
for
(
unsigned
order
=
start_order
;
order
<
queue
->
GetLength
(
);
++
order
)
{
unsigned
position
=
queue
->
OrderToPosition
(
order
);
uint8_t
priority
=
queue
->
items
[
position
].
priority
;
assert
(
priority
<=
last_priority
);
(
void
)
last_priority
;
...
...
@@ -48,74 +48,74 @@ check_descending_priority(G_GNUC_UNUSED const struct queue *queue,
int
main
(
G_GNUC_UNUSED
int
argc
,
G_GNUC_UNUSED
char
**
argv
)
{
struct
song
songs
[
16
];
st
atic
st
ruct
song
songs
[
16
];
struct
queue
queue
(
32
);
for
(
unsigned
i
=
0
;
i
<
G_N_ELEMENTS
(
songs
);
++
i
)
queue
_append
(
&
queue
,
&
songs
[
i
],
0
);
queue
.
Append
(
&
songs
[
i
],
0
);
assert
(
queue
_length
(
&
queue
)
==
G_N_ELEMENTS
(
songs
));
assert
(
queue
.
GetLength
(
)
==
G_N_ELEMENTS
(
songs
));
/* priority=10 for 4 items */
queue
_set_priority_range
(
&
queue
,
4
,
8
,
10
,
-
1
);
queue
.
SetPriorityRange
(
4
,
8
,
10
,
-
1
);
queue
.
random
=
true
;
queue
_shuffle_order
(
&
queue
);
queue
.
ShuffleOrder
(
);
check_descending_priority
(
&
queue
,
0
);
for
(
unsigned
i
=
0
;
i
<
4
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
4
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
4
);
}
for
(
unsigned
i
=
4
;
i
<
8
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
<
4
);
assert
(
queue
.
PositionToOrder
(
i
)
<
4
);
}
for
(
unsigned
i
=
8
;
i
<
G_N_ELEMENTS
(
songs
);
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
4
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
4
);
}
/* priority=50 one more item */
queue
_set_priority_range
(
&
queue
,
15
,
16
,
50
,
-
1
);
queue
.
SetPriorityRange
(
15
,
16
,
50
,
-
1
);
check_descending_priority
(
&
queue
,
0
);
assert
(
queue
_position_to_order
(
&
queue
,
15
)
==
0
);
assert
(
queue
.
PositionToOrder
(
15
)
==
0
);
for
(
unsigned
i
=
0
;
i
<
4
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
4
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
4
);
}
for
(
unsigned
i
=
4
;
i
<
8
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
1
&&
queue
_position_to_order
(
&
queue
,
i
)
<
5
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
1
&&
queue
.
PositionToOrder
(
i
)
<
5
);
}
for
(
unsigned
i
=
8
;
i
<
15
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
5
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
5
);
}
/* priority=20 for one of the 4 priority=10 items */
queue
_set_priority_range
(
&
queue
,
3
,
4
,
20
,
-
1
);
queue
.
SetPriorityRange
(
3
,
4
,
20
,
-
1
);
check_descending_priority
(
&
queue
,
0
);
assert
(
queue
_position_to_order
(
&
queue
,
3
)
==
1
);
assert
(
queue
_position_to_order
(
&
queue
,
15
)
==
0
);
assert
(
queue
.
PositionToOrder
(
3
)
==
1
);
assert
(
queue
.
PositionToOrder
(
15
)
==
0
);
for
(
unsigned
i
=
0
;
i
<
3
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
5
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
5
);
}
for
(
unsigned
i
=
4
;
i
<
8
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
2
&&
queue
_position_to_order
(
&
queue
,
i
)
<
6
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
2
&&
queue
.
PositionToOrder
(
i
)
<
6
);
}
for
(
unsigned
i
=
8
;
i
<
15
;
++
i
)
{
assert
(
queue
_position_to_order
(
&
queue
,
i
)
>=
6
);
assert
(
queue
.
PositionToOrder
(
i
)
>=
6
);
}
/* priority=20 for another one of the 4 priority=10 items;
...
...
@@ -124,17 +124,17 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
unsigned
current_order
=
4
;
unsigned
current_position
=
queue
_order_to_position
(
&
queue
,
current_order
);
queue
.
OrderToPosition
(
current_order
);
unsigned
a_order
=
3
;
unsigned
a_position
=
queue
_order_to_position
(
&
queue
,
a_order
);
unsigned
a_position
=
queue
.
OrderToPosition
(
a_order
);
assert
(
queue
.
items
[
a_position
].
priority
==
10
);
queue
_set_priority
(
&
queue
,
a_position
,
20
,
current_order
);
queue
.
SetPriority
(
a_position
,
20
,
current_order
);
current_order
=
queue
_position_to_order
(
&
queue
,
current_position
);
current_order
=
queue
.
PositionToOrder
(
current_position
);
assert
(
current_order
==
3
);
a_order
=
queue
_position_to_order
(
&
queue
,
a_position
);
a_order
=
queue
.
PositionToOrder
(
a_position
);
assert
(
a_order
==
4
);
check_descending_priority
(
&
queue
,
current_order
+
1
);
...
...
@@ -144,14 +144,14 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
just created */
unsigned
b_order
=
10
;
unsigned
b_position
=
queue
_order_to_position
(
&
queue
,
b_order
);
unsigned
b_position
=
queue
.
OrderToPosition
(
b_order
);
assert
(
queue
.
items
[
b_position
].
priority
==
0
);
queue
_set_priority
(
&
queue
,
b_position
,
70
,
current_order
);
queue
.
SetPriority
(
b_position
,
70
,
current_order
);
current_order
=
queue
_position_to_order
(
&
queue
,
current_position
);
current_order
=
queue
.
PositionToOrder
(
current_position
);
assert
(
current_order
==
3
);
b_order
=
queue
_position_to_order
(
&
queue
,
b_position
);
b_order
=
queue
.
PositionToOrder
(
b_position
);
assert
(
b_order
==
4
);
check_descending_priority
(
&
queue
,
current_order
+
1
);
...
...
@@ -161,27 +161,26 @@ main(G_GNUC_UNUSED int argc, G_GNUC_UNUSED char **argv)
hasn't changed (it was already higher before) */
unsigned
c_order
=
0
;
unsigned
c_position
=
queue
_order_to_position
(
&
queue
,
c_order
);
unsigned
c_position
=
queue
.
OrderToPosition
(
c_order
);
assert
(
queue
.
items
[
c_position
].
priority
==
50
);
queue
_set_priority
(
&
queue
,
c_position
,
60
,
current_order
);
queue
.
SetPriority
(
c_position
,
60
,
current_order
);
current_order
=
queue
_position_to_order
(
&
queue
,
current_position
);
current_order
=
queue
.
PositionToOrder
(
current_position
);
assert
(
current_order
==
3
);
c_order
=
queue
_position_to_order
(
&
queue
,
c_position
);
c_order
=
queue
.
PositionToOrder
(
c_position
);
assert
(
c_order
==
0
);
/* move the prio=20 item back */
a_order
=
queue
_position_to_order
(
&
queue
,
a_position
);
a_order
=
queue
.
PositionToOrder
(
a_position
);
assert
(
a_order
==
5
);
assert
(
queue
.
items
[
a_position
].
priority
==
20
);
queue
_set_priority
(
&
queue
,
a_position
,
5
,
current_order
);
queue
.
SetPriority
(
a_position
,
5
,
current_order
);
current_order
=
queue_position_to_order
(
&
queue
,
current_position
);
current_order
=
queue
.
PositionToOrder
(
current_position
);
assert
(
current_order
==
3
);
a_order
=
queue
_position_to_order
(
&
queue
,
a_position
);
a_order
=
queue
.
PositionToOrder
(
a_position
);
assert
(
a_order
==
6
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment