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
52638c68
Commit
52638c68
authored
Jan 07, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Playlist: convert functions to methods
parent
400ff1c8
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
634 additions
and
753 deletions
+634
-753
Makefile.am
Makefile.am
+0
-1
DatabaseQueue.cxx
src/DatabaseQueue.cxx
+1
-2
Partition.hxx
src/Partition.hxx
+122
-0
PlayerCommands.cxx
src/PlayerCommands.cxx
+26
-35
Playlist.cxx
src/Playlist.cxx
+93
-169
Playlist.hxx
src/Playlist.hxx
+128
-119
PlaylistControl.cxx
src/PlaylistControl.cxx
+86
-107
PlaylistEdit.cxx
src/PlaylistEdit.cxx
+135
-181
PlaylistGlobal.cxx
src/PlaylistGlobal.cxx
+2
-3
PlaylistInternal.hxx
src/PlaylistInternal.hxx
+0
-56
PlaylistPrint.cxx
src/PlaylistPrint.cxx
+1
-2
PlaylistQueue.cxx
src/PlaylistQueue.cxx
+1
-1
PlaylistSave.cxx
src/PlaylistSave.cxx
+4
-4
PlaylistState.cxx
src/PlaylistState.cxx
+11
-21
QueueCommands.cxx
src/QueueCommands.cxx
+23
-49
UpdateRemove.cxx
src/UpdateRemove.cxx
+1
-3
No files found.
Makefile.am
View file @
52638c68
...
...
@@ -113,7 +113,6 @@ mpd_headers = \
src/page.h
\
src/Playlist.hxx
\
src/playlist_error.h
\
src/PlaylistInternal.hxx
\
src/playlist_plugin.h
\
src/playlist_list.h
\
src/playlist/extm3u_playlist_plugin.h
\
...
...
src/DatabaseQueue.cxx
View file @
52638c68
...
...
@@ -30,8 +30,7 @@ static bool
AddToQueue
(
Partition
&
partition
,
song
&
song
,
GError
**
error_r
)
{
enum
playlist_result
result
=
playlist_append_song
(
&
partition
.
playlist
,
&
partition
.
pc
,
&
song
,
NULL
);
partition
.
playlist
.
AppendSong
(
partition
.
pc
,
&
song
,
NULL
);
if
(
result
!=
PLAYLIST_RESULT_SUCCESS
)
{
g_set_error
(
error_r
,
playlist_quark
(),
result
,
"Playlist error"
);
...
...
src/Partition.hxx
View file @
52638c68
...
...
@@ -38,6 +38,128 @@ struct Partition {
:
playlist
(
max_length
),
pc
(
buffer_chunks
,
buffered_before_play
)
{
}
void
ClearQueue
()
{
playlist
.
Clear
(
pc
);
}
enum
playlist_result
AppendFile
(
const
char
*
path_fs
,
unsigned
*
added_id
=
nullptr
)
{
return
playlist
.
AppendFile
(
pc
,
path_fs
,
added_id
);
}
enum
playlist_result
AppendURI
(
const
char
*
uri_utf8
,
unsigned
*
added_id
=
nullptr
)
{
return
playlist
.
AppendURI
(
pc
,
uri_utf8
,
added_id
);
}
enum
playlist_result
DeletePosition
(
unsigned
position
)
{
return
playlist
.
DeletePosition
(
pc
,
position
);
}
enum
playlist_result
DeleteId
(
unsigned
id
)
{
return
playlist
.
DeleteId
(
pc
,
id
);
}
/**
* Deletes a range of songs from the playlist.
*
* @param start the position of the first song to delete
* @param end the position after the last song to delete
*/
enum
playlist_result
DeleteRange
(
unsigned
start
,
unsigned
end
)
{
return
playlist
.
DeleteRange
(
pc
,
start
,
end
);
}
void
DeleteSong
(
const
song
&
song
)
{
playlist
.
DeleteSong
(
pc
,
song
);
}
void
Shuffle
(
unsigned
start
,
unsigned
end
)
{
playlist
.
Shuffle
(
pc
,
start
,
end
);
}
enum
playlist_result
MoveRange
(
unsigned
start
,
unsigned
end
,
int
to
)
{
return
playlist
.
MoveRange
(
pc
,
start
,
end
,
to
);
}
enum
playlist_result
MoveId
(
unsigned
id
,
int
to
)
{
return
playlist
.
MoveId
(
pc
,
id
,
to
);
}
enum
playlist_result
SwapPositions
(
unsigned
song1
,
unsigned
song2
)
{
return
playlist
.
SwapPositions
(
pc
,
song1
,
song2
);
}
enum
playlist_result
SwapIds
(
unsigned
id1
,
unsigned
id2
)
{
return
playlist
.
SwapIds
(
pc
,
id1
,
id2
);
}
enum
playlist_result
SetPriorityRange
(
unsigned
start_position
,
unsigned
end_position
,
uint8_t
priority
)
{
return
playlist
.
SetPriorityRange
(
pc
,
start_position
,
end_position
,
priority
);
}
enum
playlist_result
SetPriorityId
(
unsigned
song_id
,
uint8_t
priority
)
{
return
playlist
.
SetPriorityId
(
pc
,
song_id
,
priority
);
}
void
Stop
()
{
playlist
.
Stop
(
pc
);
}
enum
playlist_result
PlayPosition
(
int
position
)
{
return
playlist
.
PlayPosition
(
pc
,
position
);
}
enum
playlist_result
PlayId
(
int
id
)
{
return
playlist
.
PlayId
(
pc
,
id
);
}
void
PlayNext
()
{
return
playlist
.
PlayNext
(
pc
);
}
void
PlayPrevious
()
{
return
playlist
.
PlayPrevious
(
pc
);
}
enum
playlist_result
SeekSongPosition
(
unsigned
song_position
,
float
seek_time
)
{
return
playlist
.
SeekSongPosition
(
pc
,
song_position
,
seek_time
);
}
enum
playlist_result
SeekSongId
(
unsigned
song_id
,
float
seek_time
)
{
return
playlist
.
SeekSongId
(
pc
,
song_id
,
seek_time
);
}
enum
playlist_result
SeekCurrent
(
float
seek_time
,
bool
relative
)
{
return
playlist
.
SeekCurrent
(
pc
,
seek_time
,
relative
);
}
void
SetRepeat
(
bool
new_value
)
{
playlist
.
SetRepeat
(
pc
,
new_value
);
}
bool
GetRandom
()
const
{
return
playlist
.
GetRandom
();
}
void
SetRandom
(
bool
new_value
)
{
playlist
.
SetRandom
(
pc
,
new_value
);
}
void
SetSingle
(
bool
new_value
)
{
playlist
.
SetSingle
(
pc
,
new_value
);
}
void
SetConsume
(
bool
new_value
)
{
playlist
.
SetConsume
(
new_value
);
}
};
#endif
src/PlayerCommands.cxx
View file @
52638c68
...
...
@@ -26,6 +26,7 @@
#include "ClientInternal.hxx"
#include "Volume.hxx"
#include "OutputAll.hxx"
#include "Partition.hxx"
#include "protocol/Result.hxx"
#include "protocol/ArgParser.hxx"
...
...
@@ -34,7 +35,6 @@ extern "C" {
}
#include "replay_gain_config.h"
#include "PlayerControl.hxx"
#include <errno.h>
...
...
@@ -62,12 +62,10 @@ enum command_return
handle_play
(
Client
*
client
,
int
argc
,
char
*
argv
[])
{
int
song
=
-
1
;
enum
playlist_result
result
;
if
(
argc
==
2
&&
!
check_int
(
client
,
&
song
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_play
(
&
client
->
playlist
,
client
->
player_control
,
song
);
enum
playlist_result
result
=
client
->
partition
.
PlayPosition
(
song
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -75,13 +73,11 @@ enum command_return
handle_playid
(
Client
*
client
,
int
argc
,
char
*
argv
[])
{
int
id
=
-
1
;
enum
playlist_result
result
;
if
(
argc
==
2
&&
!
check_int
(
client
,
&
id
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_play_id
(
&
client
->
playlist
,
client
->
player_control
,
id
);
enum
playlist_result
result
=
client
->
partition
.
PlayId
(
id
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -89,7 +85,7 @@ enum command_return
handle_stop
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
G_GNUC_UNUSED
char
*
argv
[])
{
playlist_stop
(
&
client
->
playlist
,
client
->
player_control
);
client
->
partition
.
Stop
(
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -155,23 +151,23 @@ handle_status(Client *client,
COMMAND_STATUS_MIXRAMPDELAY
": %f
\n
"
COMMAND_STATUS_STATE
": %s
\n
"
,
volume_level_get
(),
playlist
_get_repeat
(
&
playlist
),
playlist
_get_random
(
&
playlist
),
playlist
_get_single
(
&
playlist
),
playlist
_get_consume
(
&
playlist
),
playlist_get_version
(
&
playlist
),
playlist
_get_length
(
&
playlist
),
playlist
.
GetRepeat
(
),
playlist
.
GetRandom
(
),
playlist
.
GetSingle
(
),
playlist
.
GetConsume
(
),
(
unsigned
long
)
playlist
.
GetVersion
(
),
playlist
.
GetLength
(
),
(
int
)(
pc_get_cross_fade
(
client
->
player_control
)
+
0.5
),
pc_get_mixramp_db
(
client
->
player_control
),
pc_get_mixramp_delay
(
client
->
player_control
),
state
);
song
=
playlist
_get_current_song
(
&
playlist
);
song
=
playlist
.
GetCurrentPosition
(
);
if
(
song
>=
0
)
{
client_printf
(
client
,
COMMAND_STATUS_SONG
": %i
\n
"
COMMAND_STATUS_SONGID
": %u
\n
"
,
song
,
playlist
_get_song_id
(
&
playlist
,
song
));
song
,
playlist
.
PositionToId
(
song
));
}
if
(
player_status
.
state
!=
PLAYER_STATE_STOP
)
{
...
...
@@ -204,12 +200,12 @@ handle_status(Client *client,
g_free
(
error
);
}
song
=
playlist
_get_next_song
(
&
playlist
);
song
=
playlist
.
GetNextPosition
(
);
if
(
song
>=
0
)
{
client_printf
(
client
,
COMMAND_STATUS_NEXTSONG
": %i
\n
"
COMMAND_STATUS_NEXTSONGID
": %u
\n
"
,
song
,
playlist
_get_song_id
(
&
playlist
,
song
));
song
,
playlist
.
PositionToId
(
song
));
}
return
COMMAND_RETURN_OK
;
...
...
@@ -226,7 +222,7 @@ handle_next(Client *client,
const
bool
single
=
playlist
.
queue
.
single
;
playlist
.
queue
.
single
=
false
;
playlist_next
(
&
playlist
,
client
->
player_control
);
client
->
partition
.
PlayNext
(
);
playlist
.
queue
.
single
=
single
;
return
COMMAND_RETURN_OK
;
...
...
@@ -236,7 +232,7 @@ enum command_return
handle_previous
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
G_GNUC_UNUSED
char
*
argv
[])
{
playlist_previous
(
&
client
->
playlist
,
client
->
player_control
);
client
->
partition
.
PlayPrevious
(
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -247,7 +243,7 @@ handle_repeat(Client *client, G_GNUC_UNUSED int argc, char *argv[])
if
(
!
check_bool
(
client
,
&
status
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
playlist_set_repeat
(
&
client
->
playlist
,
client
->
player_control
,
status
);
client
->
partition
.
SetRepeat
(
status
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -258,7 +254,7 @@ handle_single(Client *client, G_GNUC_UNUSED int argc, char *argv[])
if
(
!
check_bool
(
client
,
&
status
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
playlist_set_single
(
&
client
->
playlist
,
client
->
player_control
,
status
);
client
->
partition
.
SetSingle
(
status
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -269,7 +265,7 @@ handle_consume(Client *client, G_GNUC_UNUSED int argc, char *argv[])
if
(
!
check_bool
(
client
,
&
status
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
playlist_set_consume
(
&
client
->
playlist
,
status
);
client
->
partition
.
SetConsume
(
status
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -280,8 +276,8 @@ handle_random(Client *client, G_GNUC_UNUSED int argc, char *argv[])
if
(
!
check_bool
(
client
,
&
status
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
playlist_set_random
(
&
client
->
playlist
,
client
->
player_control
,
status
);
audio_output_all_set_replay_gain_mode
(
replay_gain_get_real_mode
(
client
->
p
laylist
.
queue
.
random
));
client
->
partition
.
SetRandom
(
status
);
audio_output_all_set_replay_gain_mode
(
replay_gain_get_real_mode
(
client
->
p
artition
.
GetRandom
()
));
return
COMMAND_RETURN_OK
;
}
...
...
@@ -297,15 +293,14 @@ enum command_return
handle_seek
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
char
*
argv
[])
{
unsigned
song
,
seek_time
;
enum
playlist_result
result
;
if
(
!
check_unsigned
(
client
,
&
song
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
if
(
!
check_unsigned
(
client
,
&
seek_time
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_seek_song
(
&
client
->
playlist
,
client
->
player_control
,
song
,
seek_time
);
enum
playlist_result
result
=
client
->
partition
.
SeekSongPosition
(
song
,
seek_time
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -313,16 +308,14 @@ enum command_return
handle_seekid
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
char
*
argv
[])
{
unsigned
id
,
seek_time
;
enum
playlist_result
result
;
if
(
!
check_unsigned
(
client
,
&
id
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
if
(
!
check_unsigned
(
client
,
&
seek_time
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_seek_song_id
(
&
client
->
playlist
,
client
->
player_control
,
id
,
seek_time
);
enum
playlist_result
result
=
client
->
partition
.
SeekSongId
(
id
,
seek_time
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -336,9 +329,7 @@ handle_seekcur(Client *client, G_GNUC_UNUSED int argc, char *argv[])
return
COMMAND_RETURN_ERROR
;
enum
playlist_result
result
=
playlist_seek_current
(
&
client
->
playlist
,
client
->
player_control
,
seek_time
,
relative
);
client
->
partition
.
SeekCurrent
(
seek_time
,
relative
);
return
print_playlist_result
(
client
,
result
);
}
...
...
src/Playlist.cxx
View file @
52638c68
...
...
@@ -18,7 +18,7 @@
*/
#include "config.h"
#include "Playlist
Internal
.hxx"
#include "Playlist.hxx"
#include "PlayerControl.hxx"
#include "song.h"
...
...
@@ -41,14 +41,14 @@ playlist_increment_version_all(struct playlist *playlist)
}
void
playlist
_tag_changed
(
struct
playlist
*
playlist
)
playlist
::
TagChanged
(
)
{
if
(
!
play
list
->
play
ing
)
if
(
!
playing
)
return
;
assert
(
playlist
->
current
>=
0
);
assert
(
current
>=
0
);
playlist
->
queue
.
ModifyAtOrder
(
playlist
->
current
);
queue
.
ModifyAtOrder
(
current
);
idle_add
(
IDLE_PLAYLIST
);
}
...
...
@@ -92,135 +92,117 @@ playlist_song_started(struct playlist *playlist, struct player_control *pc)
playlist
->
queued
=
-
1
;
if
(
playlist
->
queue
.
consume
)
playlist_delete
(
playlist
,
pc
,
playlist
->
queue
.
OrderToPosition
(
current
));
playlist
->
DeleteOrder
(
*
pc
,
current
);
idle_add
(
IDLE_PLAYER
);
}
const
struct
song
*
playlist
_get_queued_song
(
struct
playlist
*
playlist
)
playlist
::
GetQueuedSong
()
const
{
if
(
!
playlist
->
playing
||
playlist
->
queued
<
0
)
return
NULL
;
return
playlist
->
queue
.
GetOrder
(
playlist
->
queued
);
return
playing
&&
queued
>=
0
?
queue
.
GetOrder
(
queued
)
:
nullptr
;
}
void
playlist_update_queued_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
struct
song
*
prev
)
playlist
::
UpdateQueuedSong
(
player_control
&
pc
,
const
song
*
prev
)
{
int
next_order
;
const
struct
song
*
next_song
;
if
(
!
playlist
->
playing
)
if
(
!
playing
)
return
;
assert
(
!
playlist
->
queue
.
IsEmpty
());
assert
((
playlist
->
queued
<
0
)
==
(
prev
==
NULL
));
assert
(
!
queue
.
IsEmpty
());
assert
((
queued
<
0
)
==
(
prev
==
NULL
));
next_order
=
playlist
->
current
>=
0
?
playlist
->
queue
.
GetNextOrder
(
playlist
->
current
)
const
int
next_order
=
current
>=
0
?
queue
.
GetNextOrder
(
current
)
:
0
;
if
(
next_order
==
0
&&
playlist
->
queue
.
random
&&
!
playlist
->
queue
.
single
)
{
if
(
next_order
==
0
&&
queue
.
random
&&
!
queue
.
single
)
{
/* shuffle the song order again, so we get a different
order each time the playlist is played
completely */
unsigned
current_position
=
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
const
unsigned
current_position
=
queue
.
OrderToPosition
(
current
);
playlist
->
queue
.
ShuffleOrder
();
queue
.
ShuffleOrder
();
/* make sure that the
playlist->
current still points to
/* make sure that the current still points to
the current song, after the song order has been
shuffled */
playlist
->
current
=
playlist
->
queue
.
PositionToOrder
(
current_position
);
current
=
queue
.
PositionToOrder
(
current_position
);
}
if
(
next_order
>=
0
)
next_song
=
playlist
->
queue
.
GetOrder
(
next_order
);
else
next_song
=
NULL
;
const
struct
song
*
const
next_song
=
next_order
>=
0
?
queue
.
GetOrder
(
next_order
)
:
nullptr
;
if
(
prev
!=
NULL
&&
next_song
!=
prev
)
{
/* clear the currently queued song */
pc_cancel
(
pc
);
playlist
->
queued
=
-
1
;
pc_cancel
(
&
pc
);
queued
=
-
1
;
}
if
(
next_order
>=
0
)
{
if
(
next_song
!=
prev
)
playlist_queue_song_order
(
playlist
,
pc
,
next_order
);
playlist_queue_song_order
(
this
,
&
pc
,
next_order
);
else
playlist
->
queued
=
next_order
;
queued
=
next_order
;
}
}
void
playlist_play_order
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
int
orderNum
)
playlist
::
PlayOrder
(
player_control
&
pc
,
int
order
)
{
char
*
uri
;
playing
=
true
;
queued
=
-
1
;
playlist
->
playing
=
true
;
playlist
->
queued
=
-
1
;
struct
song
*
song
=
song_dup_detached
(
queue
.
GetOrder
(
order
));
struct
song
*
song
=
song_dup_detached
(
playlist
->
queue
.
GetOrder
(
orderNum
));
uri
=
song_get_uri
(
song
);
g_debug
(
"play %i:
\"
%s
\"
"
,
orderNum
,
uri
);
char
*
uri
=
song_get_uri
(
song
);
g_debug
(
"play %i:
\"
%s
\"
"
,
order
,
uri
);
g_free
(
uri
);
pc_play
(
pc
,
song
);
playlist
->
current
=
orderNum
;
pc_play
(
&
pc
,
song
);
current
=
order
;
}
static
void
playlist_resume_playback
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
);
/**
* This is the "PLAYLIST" event handler. It is invoked by the player
* thread whenever it requests a new queued song, or when it exits.
*/
void
playlist
_sync
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
)
playlist
::
SyncWithPlayer
(
player_control
&
pc
)
{
if
(
!
play
list
->
play
ing
)
if
(
!
playing
)
/* this event has reached us out of sync: we aren't
playing anymore; ignore the event */
return
;
player_lock
(
pc
);
enum
player_state
pc_state
=
pc_get_state
(
pc
);
const
s
truct
song
*
pc_next_song
=
pc
->
next_song
;
player_unlock
(
pc
);
player_lock
(
&
pc
);
const
enum
player_state
pc_state
=
pc_get_state
(
&
pc
);
const
s
ong
*
pc_next_song
=
pc
.
next_song
;
player_unlock
(
&
pc
);
if
(
pc_state
==
PLAYER_STATE_STOP
)
/* the player thread has stopped: check if playback
should be restarted with the next song. That can
happen if the playlist isn't filling the queue fast
enough */
playlist_resume_playback
(
playlist
,
pc
);
playlist_resume_playback
(
this
,
&
pc
);
else
{
/* check if the player thread has already started
playing the queued song */
if
(
pc_next_song
==
NULL
&&
playlist
->
queued
!=
-
1
)
playlist_song_started
(
playlist
,
pc
);
if
(
pc_next_song
==
nullptr
&&
queued
!=
-
1
)
playlist_song_started
(
this
,
&
pc
);
player_lock
(
pc
);
pc_next_song
=
pc
->
next_song
;
player_unlock
(
pc
);
player_lock
(
&
pc
);
pc_next_song
=
pc
.
next_song
;
player_unlock
(
&
pc
);
/* make sure the queued song is always set (if
possible) */
if
(
pc_next_song
==
NULL
&&
playlist
->
queued
<
0
)
playlist_update_queued_song
(
playlist
,
pc
,
NULL
);
if
(
pc_next_song
==
nullptr
&&
queued
<
0
)
UpdateQueuedSong
(
pc
,
nullptr
);
}
}
...
...
@@ -247,53 +229,25 @@ playlist_resume_playback(struct playlist *playlist, struct player_control *pc)
playlist
->
error_count
>=
playlist
->
queue
.
GetLength
())
/* too many errors, or critical error: stop
playback */
playlist
_stop
(
playlist
,
pc
);
playlist
->
Stop
(
*
pc
);
else
/* continue playback at the next song */
playlist_next
(
playlist
,
pc
);
}
bool
playlist_get_repeat
(
const
struct
playlist
*
playlist
)
{
return
playlist
->
queue
.
repeat
;
}
bool
playlist_get_random
(
const
struct
playlist
*
playlist
)
{
return
playlist
->
queue
.
random
;
}
bool
playlist_get_single
(
const
struct
playlist
*
playlist
)
{
return
playlist
->
queue
.
single
;
}
bool
playlist_get_consume
(
const
struct
playlist
*
playlist
)
{
return
playlist
->
queue
.
consume
;
playlist
->
PlayNext
(
*
pc
);
}
void
playlist_set_repeat
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
bool
status
)
playlist
::
SetRepeat
(
player_control
&
pc
,
bool
status
)
{
if
(
status
==
playlist
->
queue
.
repeat
)
if
(
status
==
queue
.
repeat
)
return
;
struct
queue
*
queue
=
&
playlist
->
queue
;
queue
->
repeat
=
status
;
queue
.
repeat
=
status
;
pc_set_border_pause
(
pc
,
queue
->
single
&&
!
queue
->
repeat
);
pc_set_border_pause
(
&
pc
,
queue
.
single
&&
!
queue
.
repeat
);
/* if the last song is currently being played, the "next song"
might change when repeat mode is toggled */
playlist_update_queued_song
(
playlist
,
pc
,
playlist_get_queued_song
(
playlist
));
UpdateQueuedSong
(
pc
,
GetQueuedSong
());
idle_add
(
IDLE_OPTIONS
);
}
...
...
@@ -309,117 +263,87 @@ playlist_order(struct playlist *playlist)
}
void
playlist_set_single
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
bool
status
)
playlist
::
SetSingle
(
player_control
&
pc
,
bool
status
)
{
if
(
status
==
playlist
->
queue
.
single
)
if
(
status
==
queue
.
single
)
return
;
struct
queue
*
queue
=
&
playlist
->
queue
;
queue
->
single
=
status
;
queue
.
single
=
status
;
pc_set_border_pause
(
pc
,
queue
->
single
&&
!
queue
->
repeat
);
pc_set_border_pause
(
&
pc
,
queue
.
single
&&
!
queue
.
repeat
);
/* if the last song is currently being played, the "next song"
might change when single mode is toggled */
playlist_update_queued_song
(
playlist
,
pc
,
playlist_get_queued_song
(
playlist
));
UpdateQueuedSong
(
pc
,
GetQueuedSong
());
idle_add
(
IDLE_OPTIONS
);
}
void
playlist
_set_consume
(
struct
playlist
*
playlist
,
bool
status
)
playlist
::
SetConsume
(
bool
status
)
{
if
(
status
==
playlist
->
queue
.
consume
)
if
(
status
==
queue
.
consume
)
return
;
playlist
->
queue
.
consume
=
status
;
queue
.
consume
=
status
;
idle_add
(
IDLE_OPTIONS
);
}
void
playlist_set_random
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
bool
status
)
playlist
::
SetRandom
(
player_control
&
pc
,
bool
status
)
{
const
struct
song
*
queued
;
if
(
status
==
playlist
->
queue
.
random
)
if
(
status
==
queue
.
random
)
return
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
const
queued_song
=
GetQueuedSong
(
);
playlist
->
queue
.
random
=
status
;
queue
.
random
=
status
;
if
(
playlist
->
queue
.
random
)
{
/* shuffle the queue order, but preserve
playlist->current */
if
(
queue
.
random
)
{
/* shuffle the queue order, but preserve current */
int
current_position
=
playlist
->
playing
&&
playlist
->
current
>=
0
?
(
int
)
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
:
-
1
;
const
int
current_position
=
GetCurrentPosition
();
playlist
->
queue
.
ShuffleOrder
();
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
=
playlist
->
queue
.
PositionToOrder
(
current_position
);
playlist
->
queue
.
SwapOrders
(
0
,
current_order
);
playlist
->
current
=
0
;
queue
.
PositionToOrder
(
current_position
);
queue
.
SwapOrders
(
0
,
current_order
);
current
=
0
;
}
else
playlist
->
current
=
-
1
;
current
=
-
1
;
}
else
playlist_order
(
playlist
);
playlist_order
(
this
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
idle_add
(
IDLE_OPTIONS
);
}
int
playlist
_get_current_song
(
const
struct
playlist
*
playlist
)
playlist
::
GetCurrentPosition
()
const
{
if
(
playlist
->
current
>=
0
)
return
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
return
-
1
;
return
current
>=
0
?
queue
.
OrderToPosition
(
current
)
:
-
1
;
}
int
playlist
_get_next_song
(
const
struct
playlist
*
playlist
)
playlist
::
GetNextPosition
()
const
{
if
(
playlist
->
current
>=
0
)
{
if
(
playlist
->
queue
.
single
==
1
&&
playlist
->
queue
.
repeat
==
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
playlist
->
queue
.
OrderToPosition
(
0
);
}
if
(
current
<
0
)
return
-
1
;
}
unsigned
long
playlist_get_version
(
const
struct
playlist
*
playlist
)
{
return
playlist
->
queue
.
version
;
}
int
playlist_get_length
(
const
struct
playlist
*
playlist
)
{
return
playlist
->
queue
.
GetLength
();
}
if
(
queue
.
single
&&
queue
.
repeat
)
return
queue
.
OrderToPosition
(
current
);
else
if
(
queue
.
IsValidOrder
(
current
+
1
))
return
queue
.
OrderToPosition
(
current
+
1
);
else
if
(
queue
.
repeat
)
return
queue
.
OrderToPosition
(
0
);
unsigned
playlist_get_song_id
(
const
struct
playlist
*
playlist
,
unsigned
song
)
{
return
playlist
->
queue
.
PositionToId
(
song
);
return
-
1
;
}
src/Playlist.hxx
View file @
52638c68
...
...
@@ -75,165 +75,147 @@ struct playlist {
~
playlist
()
{
}
};
void
playlist_global_init
();
uint32_t
GetVersion
()
const
{
return
queue
.
version
;
}
void
playlist_tag_changed
(
struct
playlist
*
playlist
);
unsigned
GetLength
()
const
{
return
queue
.
GetLength
();
}
unsigned
PositionToId
(
unsigned
position
)
const
{
return
queue
.
PositionToId
(
position
);
}
gcc_pure
int
GetCurrentPosition
()
const
;
/**
* Returns the "queue" object of the global playlist instance.
gcc_pure
int
GetNextPosition
()
const
;
/**
* Returns the song object which is currently queued. Returns
* none if there is none (yet?) or if MPD isn't playing.
*/
static
inline
const
struct
queue
*
playlist_get_queue
(
const
struct
playlist
*
playlist
)
{
return
&
playlist
->
queue
;
}
gcc_pure
const
struct
song
*
GetQueuedSong
()
const
;
void
playlist_clear
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
);
/**
* This is the "PLAYLIST" event handler. It is invoked by the
* player thread whenever it requests a new queued song, or
* when it exits.
*/
void
SyncWithPlayer
(
player_control
&
pc
);
/**
* Appends a local file (outside the music database) to the playlist.
protected
:
/**
* Called by all editing methods after a modification.
* Updates the queue version and emits #IDLE_PLAYLIST.
*/
void
OnModified
();
/**
* Updates the "queued song". Calculates the next song
* according to the current one (if MPD isn't playing, it
* takes the first song), and queues this song. Clears the
* old queued song if there was one.
*
* Note: the caller is responsible for checking permissions.
* @param prev the song which was previously queued, as
* determined by playlist_get_queued_song()
*/
enum
playlist_result
playlist_append_file
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
char
*
path_fs
,
unsigned
*
added_id
);
void
UpdateQueuedSong
(
player_control
&
pc
,
const
song
*
prev
);
enum
playlist_result
playlist_append_uri
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
char
*
file
,
unsigned
*
added_id
);
public
:
void
Clear
(
player_control
&
pc
);
enum
playlist_result
playlist_append_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
struct
song
*
song
,
unsigned
*
added_id
);
void
TagChanged
();
enum
playlist_result
playlist_delete
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song
);
enum
playlist_result
AppendSong
(
player_control
&
pc
,
struct
song
*
song
,
unsigned
*
added_id
=
nullptr
);
/**
* Deletes a range of songs from the playlist.
/**
* Appends a local file (outside the music database) to the
* playlist.
*
* @param start the position of the first song to delete
* @param end the position after the last song to delete
* Note: the caller is responsible for checking permissions.
*/
enum
playlist_result
playlist_delete_range
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
start
,
unsigned
end
);
enum
playlist_result
AppendFile
(
player_control
&
pc
,
const
char
*
path_fs
,
unsigned
*
added_id
=
nullptr
);
enum
playlist_result
playlist_delete_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song
);
void
playlist_stop
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
);
enum
playlist_result
AppendURI
(
player_control
&
pc
,
const
char
*
uri_utf8
,
unsigned
*
added_id
=
nullptr
);
enum
playlist_result
playlist_play
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
int
song
);
protected
:
void
DeleteInternal
(
player_control
&
pc
,
unsigned
song
,
const
struct
song
**
queued_p
);
enum
playlist_result
playlist_play_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
int
song
);
public
:
enum
playlist_result
DeletePosition
(
player_control
&
pc
,
unsigned
position
);
void
playlist_next
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
);
void
playlist_sync
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
);
enum
playlist_result
DeleteOrder
(
player_control
&
pc
,
unsigned
order
)
{
return
DeletePosition
(
pc
,
queue
.
OrderToPosition
(
order
));
}
void
playlist_previous
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
);
enum
playlist_result
DeleteId
(
player_control
&
pc
,
unsigned
id
);
void
playlist_shuffle
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
/**
* Deletes a range of songs from the playlist.
*
* @param start the position of the first song to delete
* @param end the position after the last song to delete
*/
enum
playlist_result
DeleteRange
(
player_control
&
pc
,
unsigned
start
,
unsigned
end
);
void
playlist_delete_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
struct
song
*
song
);
void
DeleteSong
(
player_control
&
pc
,
const
song
&
song
);
enum
playlist_result
playlist_move_range
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
void
Shuffle
(
player_control
&
pc
,
unsigned
start
,
unsigned
end
);
enum
playlist_result
MoveRange
(
player_control
&
pc
,
unsigned
start
,
unsigned
end
,
int
to
);
enum
playlist_result
playlist_move_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id
,
int
to
);
enum
playlist_result
MoveId
(
player_control
&
pc
,
unsigned
id
,
int
to
);
enum
playlist_result
playlist_swap_songs
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
enum
playlist_result
SwapPositions
(
player_control
&
pc
,
unsigned
song1
,
unsigned
song2
);
enum
playlist_result
playlist_swap_songs_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
enum
playlist_result
SwapIds
(
player_control
&
pc
,
unsigned
id1
,
unsigned
id2
);
enum
playlist_result
playlist_set_priority
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
start_position
,
unsigned
end_position
,
enum
playlist_result
SetPriorityRange
(
player_control
&
pc
,
unsigned
start_position
,
unsigned
end_position
,
uint8_t
priority
);
enum
playlist_result
playlist_set_priority_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
enum
playlist_result
SetPriorityId
(
player_control
&
pc
,
unsigned
song_id
,
uint8_t
priority
);
bool
playlist_get_repeat
(
const
struct
playlist
*
playlist
);
void
playlist_set_repeat
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
bool
status
);
bool
playlist_get_random
(
const
struct
playlist
*
playlist
);
void
playlist_set_random
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
bool
status
);
bool
playlist_get_single
(
const
struct
playlist
*
playlist
);
void
playlist_set_single
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
bool
status
);
bool
playlist_get_consume
(
const
struct
playlist
*
playlist
);
void
playlist_set_consume
(
struct
playlist
*
playlist
,
bool
status
);
void
Stop
(
player_control
&
pc
);
int
playlist_get_current_song
(
const
struct
playlist
*
playlist
);
enum
playlist_result
PlayPosition
(
player_control
&
pc
,
int
position
);
int
playlist_get_next_song
(
const
struct
playlist
*
playlist
);
void
PlayOrder
(
player_control
&
pc
,
int
order
);
unsigned
playlist_get_song_id
(
const
struct
playlist
*
playlist
,
unsigned
song
);
enum
playlist_result
PlayId
(
player_control
&
pc
,
int
id
);
int
playlist_get_length
(
const
struct
playlist
*
playlist
);
void
PlayNext
(
player_control
&
pc
);
unsigned
long
playlist_get_version
(
const
struct
playlist
*
playlist
);
void
PlayPrevious
(
player_control
&
pc
);
enum
playlist_result
playlist_seek_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song
,
float
seek_time
);
enum
playlist_result
SeekSongPosition
(
player_control
&
pc
,
unsigned
song_position
,
float
seek_time
);
enum
playlist_result
playlist_seek_song_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id
,
float
seek_time
);
enum
playlist_result
SeekSongId
(
player_control
&
pc
,
unsigned
song_id
,
float
seek_time
);
/**
/**
* Seek within the current song. Fails if MPD is not currently
* playing.
*
...
...
@@ -241,10 +223,37 @@ playlist_seek_song_id(struct playlist *playlist, struct player_control *pc,
* @param relative if true, then the specified time is relative to the
* current position
*/
enum
playlist_result
playlist_seek_current
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
enum
playlist_result
SeekCurrent
(
player_control
&
pc
,
float
seek_time
,
bool
relative
);
bool
GetRepeat
()
const
{
return
queue
.
repeat
;
}
void
SetRepeat
(
player_control
&
pc
,
bool
new_value
);
bool
GetRandom
()
const
{
return
queue
.
random
;
}
void
SetRandom
(
player_control
&
pc
,
bool
new_value
);
bool
GetSingle
()
const
{
return
queue
.
single
;
}
void
SetSingle
(
player_control
&
pc
,
bool
new_value
);
bool
GetConsume
()
const
{
return
queue
.
consume
;
}
void
SetConsume
(
bool
new_value
);
};
void
playlist_global_init
();
void
playlist_increment_version_all
(
struct
playlist
*
playlist
);
...
...
src/PlaylistControl.cxx
View file @
52638c68
...
...
@@ -23,7 +23,7 @@
*/
#include "config.h"
#include "Playlist
Internal
.hxx"
#include "Playlist.hxx"
#include "PlayerControl.hxx"
#include "song.h"
...
...
@@ -33,244 +33,223 @@
#define G_LOG_DOMAIN "playlist"
void
playlist
_stop
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
)
playlist
::
Stop
(
player_control
&
pc
)
{
if
(
!
play
list
->
play
ing
)
if
(
!
playing
)
return
;
assert
(
playlist
->
current
>=
0
);
assert
(
current
>=
0
);
g_debug
(
"stop"
);
pc_stop
(
pc
);
playlist
->
queued
=
-
1
;
play
list
->
play
ing
=
false
;
pc_stop
(
&
pc
);
queued
=
-
1
;
playing
=
false
;
if
(
playlist
->
queue
.
random
)
{
if
(
queue
.
random
)
{
/* shuffle the playlist, so the next playback will
result in a new random order */
unsigned
current_position
=
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
unsigned
current_position
=
queue
.
OrderToPosition
(
current
);
playlist
->
queue
.
ShuffleOrder
();
queue
.
ShuffleOrder
();
/* make sure that "current" stays valid, and the next
"play" command plays the same song again */
playlist
->
current
=
playlist
->
queue
.
PositionToOrder
(
current_position
);
current
=
queue
.
PositionToOrder
(
current_position
);
}
}
enum
playlist_result
playlist_play
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
int
song
)
playlist
::
PlayPosition
(
player_control
&
pc
,
int
song
)
{
unsigned
i
=
song
;
pc_clear_error
(
pc
);
pc_clear_error
(
&
pc
);
unsigned
i
=
song
;
if
(
song
==
-
1
)
{
/* play any song ("current" song, or the first song */
if
(
playlist
->
queue
.
IsEmpty
())
if
(
queue
.
IsEmpty
())
return
PLAYLIST_RESULT_SUCCESS
;
if
(
play
list
->
play
ing
)
{
if
(
playing
)
{
/* already playing: unpause playback, just in
case it was paused, and return */
pc_set_pause
(
pc
,
false
);
pc_set_pause
(
&
pc
,
false
);
return
PLAYLIST_RESULT_SUCCESS
;
}
/* select a song: "current" song, or the first one */
i
=
playlist
->
current
>=
0
?
playlist
->
current
i
=
current
>=
0
?
current
:
0
;
}
else
if
(
!
playlist
->
queue
.
IsValidPosition
(
song
))
}
else
if
(
!
queue
.
IsValidPosition
(
song
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
(
playlist
->
queue
.
random
)
{
if
(
queue
.
random
)
{
if
(
song
>=
0
)
/* "i" is currently the song position (which
would be equal to the order number in
no-random mode); convert it to a order
number, because random mode is enabled */
i
=
playlist
->
queue
.
PositionToOrder
(
song
);
i
=
queue
.
PositionToOrder
(
song
);
if
(
!
play
list
->
play
ing
)
playlist
->
current
=
0
;
if
(
!
playing
)
current
=
0
;
/* swap the new song with the previous "current" one,
so playback continues as planned */
playlist
->
queue
.
SwapOrders
(
i
,
playlist
->
current
);
i
=
playlist
->
current
;
queue
.
SwapOrders
(
i
,
current
);
i
=
current
;
}
playlist
->
stop_on_error
=
false
;
playlist
->
error_count
=
0
;
stop_on_error
=
false
;
error_count
=
0
;
playlist_play_order
(
playlist
,
pc
,
i
);
PlayOrder
(
pc
,
i
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist_play_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
int
id
)
playlist
::
PlayId
(
player_control
&
pc
,
int
id
)
{
int
song
;
if
(
id
==
-
1
)
{
return
playlist_play
(
playlist
,
pc
,
id
);
}
if
(
id
==
-
1
)
return
PlayPosition
(
pc
,
id
);
song
=
playlist
->
queue
.
IdToPosition
(
id
);
int
song
=
queue
.
IdToPosition
(
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_play
(
playlist
,
pc
,
song
);
return
PlayPosition
(
pc
,
song
);
}
void
playlist
_next
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
)
playlist
::
PlayNext
(
player_control
&
pc
)
{
int
next_order
;
int
current
;
if
(
!
playlist
->
playing
)
if
(
!
playing
)
return
;
assert
(
!
playlist
->
queue
.
IsEmpty
());
assert
(
playlist
->
queue
.
IsValidOrder
(
playlist
->
current
));
assert
(
!
queue
.
IsEmpty
());
assert
(
queue
.
IsValidOrder
(
current
));
c
urrent
=
playlist
->
current
;
playlist
->
stop_on_error
=
false
;
c
onst
int
old_current
=
current
;
stop_on_error
=
false
;
/* determine the next song from the queue's order list */
next_order
=
playlist
->
queue
.
GetNextOrder
(
playlist
->
current
);
const
int
next_order
=
queue
.
GetNextOrder
(
current
);
if
(
next_order
<
0
)
{
/* no song after this one: stop playback */
playlist_stop
(
playlist
,
pc
);
Stop
(
pc
);
/* reset "current song" */
playlist
->
current
=
-
1
;
current
=
-
1
;
}
else
{
if
(
next_order
==
0
&&
playlist
->
queue
.
random
)
{
if
(
next_order
==
0
&&
queue
.
random
)
{
/* The queue told us that the next song is the first
song. This means we are in repeat mode. Shuffle
the queue order, so this time, the user hears the
songs in a different than before */
assert
(
playlist
->
queue
.
repeat
);
assert
(
queue
.
repeat
);
playlist
->
queue
.
ShuffleOrder
();
queue
.
ShuffleOrder
();
/* note that
playlist->current and playlist->
queued are
/* note that
current and
queued are
now invalid, but playlist_play_order() will
discard them anyway */
}
playlist_play_order
(
playlist
,
pc
,
next_order
);
PlayOrder
(
pc
,
next_order
);
}
/* Consume mode removes each played songs. */
if
(
playlist
->
queue
.
consume
)
playlist_delete
(
playlist
,
pc
,
playlist
->
queue
.
OrderToPosition
(
current
));
if
(
queue
.
consume
)
DeleteOrder
(
pc
,
old_current
);
}
void
playlist
_previous
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
)
playlist
::
PlayPrevious
(
player_control
&
pc
)
{
if
(
!
play
list
->
play
ing
)
if
(
!
playing
)
return
;
assert
(
playlist
->
queue
.
GetLength
()
>
0
);
assert
(
!
queue
.
IsEmpty
()
);
if
(
playlist
->
current
>
0
)
{
int
order
;
if
(
current
>
0
)
{
/* play the preceding song */
playlist_play_order
(
playlist
,
pc
,
playlist
->
current
-
1
);
}
else
if
(
playlist
->
queue
.
repeat
)
{
order
=
current
-
1
;
}
else
if
(
queue
.
repeat
)
{
/* play the last song in "repeat" mode */
playlist_play_order
(
playlist
,
pc
,
playlist
->
queue
.
GetLength
()
-
1
);
order
=
queue
.
GetLength
()
-
1
;
}
else
{
/* re-start playing the current song if it's
the first one */
playlist_play_order
(
playlist
,
pc
,
playlist
->
current
)
;
order
=
current
;
}
PlayOrder
(
pc
,
order
);
}
enum
playlist_result
playlist_seek_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song
,
float
seek_time
)
playlist
::
SeekSongPosition
(
player_control
&
pc
,
unsigned
song
,
float
seek_time
)
{
const
struct
song
*
queued
;
unsigned
i
;
bool
success
;
if
(
!
playlist
->
queue
.
IsValidPosition
(
song
))
if
(
!
queue
.
IsValidPosition
(
song
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
queued_song
=
GetQueuedSong
(
);
if
(
playlist
->
queue
.
random
)
i
=
playlist
->
queue
.
PositionToOrder
(
song
);
else
i
=
song
;
unsigned
i
=
queue
.
random
?
queue
.
PositionToOrder
(
song
)
:
song
;
pc_clear_error
(
pc
);
playlist
->
stop_on_error
=
true
;
playlist
->
error_count
=
0
;
pc_clear_error
(
&
pc
);
stop_on_error
=
true
;
error_count
=
0
;
if
(
!
play
list
->
playing
||
(
unsigned
)
playlist
->
current
!=
i
)
{
if
(
!
play
ing
||
(
unsigned
)
current
!=
i
)
{
/* seeking is not within the current song - prepare
song change */
play
list
->
play
ing
=
true
;
playlist
->
current
=
i
;
playing
=
true
;
current
=
i
;
queued
=
NULL
;
queued
_song
=
nullptr
;
}
struct
song
*
the_song
=
song_dup_detached
(
playlist
->
queue
.
GetOrder
(
i
));
success
=
pc_seek
(
pc
,
the_song
,
seek_time
);
if
(
!
success
)
{
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
struct
song
*
the_song
=
song_dup_detached
(
queue
.
GetOrder
(
i
));
if
(
!
pc_seek
(
&
pc
,
the_song
,
seek_time
))
{
UpdateQueuedSong
(
pc
,
queued_song
);
return
PLAYLIST_RESULT_NOT_PLAYING
;
}
playlist
->
queued
=
-
1
;
playlist_update_queued_song
(
playlist
,
pc
,
NULL
);
queued
=
-
1
;
UpdateQueuedSong
(
pc
,
NULL
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist_seek_song_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id
,
float
seek_time
)
playlist
::
SeekSongId
(
player_control
&
pc
,
unsigned
id
,
float
seek_time
)
{
int
song
=
playlist
->
queue
.
IdToPosition
(
id
);
int
song
=
queue
.
IdToPosition
(
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_seek_song
(
playlist
,
pc
,
song
,
seek_time
);
return
SeekSongPosition
(
pc
,
song
,
seek_time
);
}
enum
playlist_result
playlist_seek_current
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
float
seek_time
,
bool
relative
)
playlist
::
SeekCurrent
(
player_control
&
pc
,
float
seek_time
,
bool
relative
)
{
if
(
!
play
list
->
play
ing
)
if
(
!
playing
)
return
PLAYLIST_RESULT_NOT_PLAYING
;
if
(
relative
)
{
struct
player_status
status
;
pc_get_status
(
pc
,
&
status
);
pc_get_status
(
&
pc
,
&
status
);
if
(
status
.
state
!=
PLAYER_STATE_PLAY
&&
status
.
state
!=
PLAYER_STATE_PAUSE
)
...
...
@@ -282,5 +261,5 @@ playlist_seek_current(struct playlist *playlist, struct player_control *pc,
if
(
seek_time
<
0
)
seek_time
=
0
;
return
playlist_seek_song
(
playlist
,
pc
,
playlist
->
current
,
seek_time
);
return
SeekSongPosition
(
pc
,
current
,
seek_time
);
}
src/PlaylistEdit.cxx
View file @
52638c68
...
...
@@ -24,7 +24,7 @@
*/
#include "config.h"
#include "Playlist
Internal
.hxx"
#include "Playlist.hxx"
#include "PlayerControl.hxx"
extern
"C"
{
...
...
@@ -38,67 +38,64 @@ extern "C" {
#include <stdlib.h>
static
void
playlist_increment_version
(
struct
playlist
*
playlist
)
void
playlist
::
OnModified
()
{
playlist
->
queue
.
IncrementVersion
();
queue
.
IncrementVersion
();
idle_add
(
IDLE_PLAYLIST
);
}
void
playlist
_clear
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
)
playlist
::
Clear
(
player_control
&
pc
)
{
playlist_stop
(
playlist
,
pc
);
playlist
->
queue
.
Clear
();
Stop
(
pc
);
playlist
->
current
=
-
1
;
queue
.
Clear
();
current
=
-
1
;
playlist_increment_version
(
playlist
);
OnModified
(
);
}
enum
playlist_result
playlist
_append_file
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
playlist
::
AppendFile
(
struct
player_control
&
pc
,
const
char
*
path_fs
,
unsigned
*
added_id
)
{
struct
song
*
song
=
song_file_load
(
path_fs
,
NULL
);
if
(
song
==
NULL
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_append_song
(
playlist
,
pc
,
song
,
added_id
);
return
AppendSong
(
pc
,
song
,
added_id
);
}
enum
playlist_result
playlist
_append_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
playlist
::
AppendSong
(
struct
player_control
&
pc
,
struct
song
*
song
,
unsigned
*
added_id
)
{
const
struct
song
*
queued
;
unsigned
id
;
if
(
playlist
->
queue
.
IsFull
())
if
(
queue
.
IsFull
())
return
PLAYLIST_RESULT_TOO_LARGE
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
const
queued_song
=
GetQueuedSong
(
);
id
=
playlist
->
queue
.
Append
(
song
,
0
);
id
=
queue
.
Append
(
song
,
0
);
if
(
playlist
->
queue
.
random
)
{
if
(
queue
.
random
)
{
/* shuffle the new song into the list of remaining
songs to play */
unsigned
start
;
if
(
playlist
->
queued
>=
0
)
start
=
playlist
->
queued
+
1
;
if
(
queued
>=
0
)
start
=
queued
+
1
;
else
start
=
playlist
->
current
+
1
;
if
(
start
<
playlist
->
queue
.
GetLength
())
playlist
->
queue
.
ShuffleOrderLast
(
start
,
playlist
->
queue
.
GetLength
());
start
=
current
+
1
;
if
(
start
<
queue
.
GetLength
())
queue
.
ShuffleOrderLast
(
start
,
queue
.
GetLength
());
}
playlist_increment_version
(
playlist
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
();
if
(
added_id
)
*
added_id
=
id
;
...
...
@@ -107,7 +104,7 @@ playlist_append_song(struct playlist *playlist, struct player_control *pc,
}
enum
playlist_result
playlist
_append_uri
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
playlist
::
AppendURI
(
struct
player_control
&
pc
,
const
char
*
uri
,
unsigned
*
added_id
)
{
g_debug
(
"add to playlist: %s"
,
uri
);
...
...
@@ -126,8 +123,7 @@ playlist_append_uri(struct playlist *playlist, struct player_control *pc,
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
}
enum
playlist_result
result
=
playlist_append_song
(
playlist
,
pc
,
song
,
added_id
);
enum
playlist_result
result
=
AppendSong
(
pc
,
song
,
added_id
);
if
(
db
!=
nullptr
)
db
->
ReturnSong
(
song
);
...
...
@@ -135,335 +131,293 @@ playlist_append_uri(struct playlist *playlist, struct player_control *pc,
}
enum
playlist_result
playlist_swap_songs
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song1
,
unsigned
song2
)
playlist
::
SwapPositions
(
player_control
&
pc
,
unsigned
song1
,
unsigned
song2
)
{
const
struct
song
*
queued
;
if
(
!
playlist
->
queue
.
IsValidPosition
(
song1
)
||
!
playlist
->
queue
.
IsValidPosition
(
song2
))
if
(
!
queue
.
IsValidPosition
(
song1
)
||
!
queue
.
IsValidPosition
(
song2
))
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
const
queued_song
=
GetQueuedSong
(
);
playlist
->
queue
.
SwapPositions
(
song1
,
song2
);
queue
.
SwapPositions
(
song1
,
song2
);
if
(
playlist
->
queue
.
random
)
{
/* update the queue order, so that
playlist->
current
if
(
queue
.
random
)
{
/* update the queue order, so that current
still points to the current song order */
playlist
->
queue
.
SwapOrders
(
playlist
->
queue
.
PositionToOrder
(
song1
),
playlist
->
queue
.
PositionToOrder
(
song2
));
queue
.
SwapOrders
(
queue
.
PositionToOrder
(
song1
),
queue
.
PositionToOrder
(
song2
));
}
else
{
/* correct the "current" song order */
if
(
playlist
->
current
==
(
int
)
song1
)
playlist
->
current
=
song2
;
else
if
(
playlist
->
current
==
(
int
)
song2
)
playlist
->
current
=
song1
;
if
(
current
==
(
int
)
song1
)
current
=
song2
;
else
if
(
current
==
(
int
)
song2
)
current
=
song1
;
}
playlist_increment_version
(
playlist
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
();
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist_swap_songs_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id1
,
unsigned
id2
)
playlist
::
SwapIds
(
player_control
&
pc
,
unsigned
id1
,
unsigned
id2
)
{
int
song1
=
playlist
->
queue
.
IdToPosition
(
id1
);
int
song2
=
playlist
->
queue
.
IdToPosition
(
id2
);
int
song1
=
queue
.
IdToPosition
(
id1
);
int
song2
=
queue
.
IdToPosition
(
id2
);
if
(
song1
<
0
||
song2
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_swap_songs
(
playlist
,
pc
,
song1
,
song2
);
return
SwapPositions
(
pc
,
song1
,
song2
);
}
enum
playlist_result
playlist
_set_priority
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
playlist
::
SetPriorityRange
(
player_control
&
pc
,
unsigned
start
,
unsigned
end
,
uint8_t
priority
)
{
if
(
start
>=
playlist
->
queue
.
GetLength
())
if
(
start
>=
GetLength
())
return
PLAYLIST_RESULT_BAD_RANGE
;
if
(
end
>
playlist
->
queue
.
GetLength
())
end
=
playlist
->
queue
.
GetLength
();
if
(
end
>
GetLength
())
end
=
GetLength
();
if
(
start
>=
end
)
return
PLAYLIST_RESULT_SUCCESS
;
/* remember "current" and "queued" */
int
current_position
=
playlist
->
current
>=
0
?
(
int
)
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
:
-
1
;
const
struct
song
*
queued
=
playlist_get_queued_song
(
playlist
);
const
int
current_position
=
GetCurrentPosition
();
const
struct
song
*
const
queued_song
=
GetQueuedSong
();
/* apply the priority changes */
playlist
->
queue
.
SetPriorityRange
(
start
,
end
,
priority
,
playlist
->
current
);
playlist_increment_version
(
playlist
);
queue
.
SetPriorityRange
(
start
,
end
,
priority
,
current
);
/* restore "current" and choose a new "queued" */
if
(
current_position
>=
0
)
playlist
->
current
=
playlist
->
queue
.
PositionToOrder
(
current_position
);
current
=
queue
.
PositionToOrder
(
current_position
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
();
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist
_set_priority_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
playlist
::
SetPriorityId
(
struct
player_control
&
pc
,
unsigned
song_id
,
uint8_t
priority
)
{
int
song_position
=
playlist
->
queue
.
IdToPosition
(
song_id
);
int
song_position
=
queue
.
IdToPosition
(
song_id
);
if
(
song_position
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_set_priority
(
playlist
,
pc
,
song_position
,
song_position
+
1
,
return
SetPriorityRange
(
pc
,
song_position
,
song_position
+
1
,
priority
);
}
static
void
playlist
_delete_internal
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
void
playlist
::
DeleteInternal
(
player_control
&
pc
,
unsigned
song
,
const
struct
song
**
queued_p
)
{
unsigned
songOrder
;
assert
(
song
<
playlist
->
queue
.
GetLength
());
assert
(
song
<
GetLength
());
songOrder
=
playlist
->
queue
.
PositionToOrder
(
song
);
unsigned
songOrder
=
queue
.
PositionToOrder
(
song
);
if
(
play
list
->
playing
&&
playlist
->
current
==
(
int
)
songOrder
)
{
bool
paused
=
pc_get_state
(
pc
)
==
PLAYER_STATE_PAUSE
;
if
(
play
ing
&&
current
==
(
int
)
songOrder
)
{
bool
paused
=
pc_get_state
(
&
pc
)
==
PLAYER_STATE_PAUSE
;
/* the current song is going to be deleted: stop the player */
pc_stop
(
pc
);
play
list
->
play
ing
=
false
;
pc_stop
(
&
pc
);
playing
=
false
;
/* see which song is going to be played instead */
playlist
->
current
=
playlist
->
queue
.
GetNextOrder
(
playlist
->
current
);
if
(
playlist
->
current
==
(
int
)
songOrder
)
playlist
->
current
=
-
1
;
current
=
queue
.
GetNextOrder
(
current
);
if
(
current
==
(
int
)
songOrder
)
current
=
-
1
;
if
(
playlist
->
current
>=
0
&&
!
paused
)
if
(
current
>=
0
&&
!
paused
)
/* play the song after the deleted one */
playlist_play_order
(
playlist
,
pc
,
playlist
->
current
);
PlayOrder
(
pc
,
current
);
else
/* no songs left to play, stop playback
completely */
playlist_stop
(
playlist
,
pc
);
Stop
(
pc
);
*
queued_p
=
NULL
;
}
else
if
(
playlist
->
current
==
(
int
)
songOrder
)
}
else
if
(
current
==
(
int
)
songOrder
)
/* there's a "current song" but we're not playing
currently - clear "current" */
playlist
->
current
=
-
1
;
current
=
-
1
;
/* now do it: remove the song */
playlist
->
queue
.
DeletePosition
(
song
);
queue
.
DeletePosition
(
song
);
/* update the "current" and "queued" variables */
if
(
playlist
->
current
>
(
int
)
songOrder
)
{
playlist
->
current
--
;
}
if
(
current
>
(
int
)
songOrder
)
current
--
;
}
enum
playlist_result
playlist_delete
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
song
)
playlist
::
DeletePosition
(
struct
player_control
&
pc
,
unsigned
song
)
{
const
struct
song
*
queued
;
if
(
song
>=
playlist
->
queue
.
GetLength
())
if
(
song
>=
queue
.
GetLength
())
return
PLAYLIST_RESULT_BAD_RANGE
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
queued_song
=
GetQueuedSong
(
);
playlist_delete_internal
(
playlist
,
pc
,
song
,
&
queued
);
DeleteInternal
(
pc
,
song
,
&
queued_song
);
playlist_increment_version
(
playlist
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
(
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist_delete_range
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
start
,
unsigned
end
)
playlist
::
DeleteRange
(
struct
player_control
&
pc
,
unsigned
start
,
unsigned
end
)
{
const
struct
song
*
queued
;
if
(
start
>=
playlist
->
queue
.
GetLength
())
if
(
start
>=
queue
.
GetLength
())
return
PLAYLIST_RESULT_BAD_RANGE
;
if
(
end
>
playlist
->
queue
.
GetLength
())
end
=
playlist
->
queue
.
GetLength
();
if
(
end
>
queue
.
GetLength
())
end
=
queue
.
GetLength
();
if
(
start
>=
end
)
return
PLAYLIST_RESULT_SUCCESS
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
queued_song
=
GetQueuedSong
(
);
do
{
playlist_delete_internal
(
playlist
,
pc
,
--
end
,
&
queued
);
DeleteInternal
(
pc
,
--
end
,
&
queued_song
);
}
while
(
end
!=
start
);
playlist_increment_version
(
playlist
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
(
);
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist_delete_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id
)
playlist
::
DeleteId
(
struct
player_control
&
pc
,
unsigned
id
)
{
int
song
=
playlist
->
queue
.
IdToPosition
(
id
);
int
song
=
queue
.
IdToPosition
(
id
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_delete
(
playlist
,
pc
,
song
);
return
DeletePosition
(
pc
,
song
);
}
void
playlist_delete_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
struct
song
*
song
)
playlist
::
DeleteSong
(
struct
player_control
&
pc
,
const
struct
song
&
song
)
{
for
(
int
i
=
playlist
->
queue
.
GetLength
()
-
1
;
i
>=
0
;
--
i
)
if
(
song
==
playlist
->
queue
.
Get
(
i
))
playlist_delete
(
playlist
,
pc
,
i
);
for
(
int
i
=
queue
.
GetLength
()
-
1
;
i
>=
0
;
--
i
)
// TODO: compare URI instead of pointer
if
(
&
song
==
queue
.
Get
(
i
))
DeletePosition
(
pc
,
i
);
}
enum
playlist_result
playlist_move_range
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
start
,
unsigned
end
,
int
to
)
playlist
::
MoveRange
(
player_control
&
pc
,
unsigned
start
,
unsigned
end
,
int
to
)
{
const
struct
song
*
queued
;
int
currentSong
;
if
(
!
playlist
->
queue
.
IsValidPosition
(
start
)
||
!
playlist
->
queue
.
IsValidPosition
(
end
-
1
))
if
(
!
queue
.
IsValidPosition
(
start
)
||
!
queue
.
IsValidPosition
(
end
-
1
))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
to
>=
0
&&
to
+
end
-
start
-
1
>=
playlist
->
queue
.
GetLength
())
||
(
to
<
0
&&
abs
(
to
)
>
(
int
)
playlist
->
queue
.
GetLength
()))
if
((
to
>=
0
&&
to
+
end
-
start
-
1
>=
GetLength
())
||
(
to
<
0
&&
unsigned
(
abs
(
to
))
>
GetLength
()))
return
PLAYLIST_RESULT_BAD_RANGE
;
if
((
int
)
start
==
to
)
/* nothing happens */
return
PLAYLIST_RESULT_SUCCESS
;
queued
=
playlist_get_queued_song
(
playlist
);
const
struct
song
*
const
queued_song
=
GetQueuedSong
(
);
/*
* (to < 0) => move to offset from current song
* (-playlist.length == to) => move to position BEFORE current song
*/
currentSong
=
playlist
->
current
>=
0
?
(
int
)
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
)
:
-
1
;
if
(
to
<
0
&&
playlist
->
current
>=
0
)
{
const
int
currentSong
=
GetCurrentPosition
();
if
(
to
<
0
&&
currentSong
>=
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
))
%
playlist
->
queue
.
GetLength
();
to
=
(
currentSong
+
abs
(
to
))
%
GetLength
();
if
(
start
<
(
unsigned
)
to
)
to
--
;
}
playlist
->
queue
.
MoveRange
(
start
,
end
,
to
);
queue
.
MoveRange
(
start
,
end
,
to
);
if
(
!
playlist
->
queue
.
random
)
{
if
(
!
queue
.
random
)
{
/* update current/queued */
if
((
int
)
start
<=
playlist
->
current
&&
(
unsigned
)
playlist
->
current
<
end
)
playlist
->
current
+=
to
-
start
;
else
if
(
playlist
->
current
>=
(
int
)
end
&&
playlist
->
current
<=
to
)
{
playlist
->
current
-=
end
-
start
;
}
else
if
(
playlist
->
current
>=
to
&&
playlist
->
current
<
(
int
)
start
)
{
playlist
->
current
+=
end
-
start
;
if
((
int
)
start
<=
current
&&
(
unsigned
)
current
<
end
)
current
+=
to
-
start
;
else
if
(
current
>=
(
int
)
end
&&
current
<=
to
)
current
-=
end
-
start
;
else
if
(
current
>=
to
&&
current
<
(
int
)
start
)
current
+=
end
-
start
;
}
}
playlist_increment_version
(
playlist
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
();
return
PLAYLIST_RESULT_SUCCESS
;
}
enum
playlist_result
playlist_move_id
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
id1
,
int
to
)
playlist
::
MoveId
(
player_control
&
pc
,
unsigned
id1
,
int
to
)
{
int
song
=
playlist
->
queue
.
IdToPosition
(
id1
);
int
song
=
queue
.
IdToPosition
(
id1
);
if
(
song
<
0
)
return
PLAYLIST_RESULT_NO_SUCH_SONG
;
return
playlist_move_range
(
playlist
,
pc
,
song
,
song
+
1
,
to
);
return
MoveRange
(
pc
,
song
,
song
+
1
,
to
);
}
void
playlist_shuffle
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
unsigned
start
,
unsigned
end
)
playlist
::
Shuffle
(
player_control
&
pc
,
unsigned
start
,
unsigned
end
)
{
const
struct
song
*
queued
;
if
(
end
>
playlist
->
queue
.
GetLength
())
if
(
end
>
GetLength
())
/* correct the "end" offset */
end
=
playlist
->
queue
.
GetLength
();
end
=
GetLength
();
if
(
(
start
+
1
)
>=
end
)
if
(
start
+
1
>=
end
)
/* needs at least two entries. */
return
;
queued
=
playlist_get_queued_song
(
playlist
);
if
(
playlist
->
playing
&&
playlist
->
current
>=
0
)
{
unsigned
current_position
;
current_position
=
playlist
->
queue
.
OrderToPosition
(
playlist
->
current
);
const
struct
song
*
const
queued_song
=
GetQueuedSong
();
if
(
playing
&&
current
>=
0
)
{
unsigned
current_position
=
queue
.
OrderToPosition
(
current
);
if
(
current_position
>=
start
&&
current_position
<
end
)
{
if
(
current_position
>=
start
&&
current_position
<
end
)
{
/* put current playing song first */
playlist
->
queue
.
SwapPositions
(
start
,
current_position
);
queue
.
SwapPositions
(
start
,
current_position
);
if
(
playlist
->
queue
.
random
)
{
playlist
->
current
=
playlist
->
queue
.
PositionToOrder
(
start
);
if
(
queue
.
random
)
{
current
=
queue
.
PositionToOrder
(
start
);
}
else
playlist
->
current
=
start
;
current
=
start
;
/* start shuffle after the current song */
start
++
;
}
}
else
{
/* no playback currently: reset
playlist->
current */
/* no playback currently: reset current */
playlist
->
current
=
-
1
;
current
=
-
1
;
}
playlist
->
queue
.
ShuffleRange
(
start
,
end
);
playlist_increment_version
(
playlist
);
queue
.
ShuffleRange
(
start
,
end
);
playlist_update_queued_song
(
playlist
,
pc
,
queued
);
UpdateQueuedSong
(
pc
,
queued_song
);
OnModified
();
}
src/PlaylistGlobal.cxx
View file @
52638c68
...
...
@@ -34,14 +34,13 @@ extern "C" {
static
void
playlist_tag_event
(
void
)
{
playlist_tag_changed
(
&
global_partition
->
playlist
);
global_partition
->
playlist
.
TagChanged
(
);
}
static
void
playlist_event
(
void
)
{
playlist_sync
(
&
global_partition
->
playlist
,
&
global_partition
->
pc
);
global_partition
->
playlist
.
SyncWithPlayer
(
global_partition
->
pc
);
}
void
...
...
src/PlaylistInternal.hxx
deleted
100644 → 0
View file @
400ff1c8
/*
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/*
* Internal header for the components of the playlist code.
*
*/
#ifndef MPD_PLAYLIST_INTERNAL_HXX
#define MPD_PLAYLIST_INTERNAL_HXX
#include "Playlist.hxx"
struct
player_control
;
/**
* Returns the song object which is currently queued. Returns none if
* there is none (yet?) or if MPD isn't playing.
*/
const
struct
song
*
playlist_get_queued_song
(
struct
playlist
*
playlist
);
/**
* Updates the "queued song". Calculates the next song according to
* the current one (if MPD isn't playing, it takes the first song),
* and queues this song. Clears the old queued song if there was one.
*
* @param prev the song which was previously queued, as determined by
* playlist_get_queued_song()
*/
void
playlist_update_queued_song
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
const
struct
song
*
prev
);
void
playlist_play_order
(
struct
playlist
*
playlist
,
struct
player_control
*
pc
,
int
orderNum
);
#endif
src/PlaylistPrint.cxx
View file @
52638c68
...
...
@@ -80,8 +80,7 @@ playlist_print_id(Client *client, const struct playlist *playlist,
bool
playlist_print_current
(
Client
*
client
,
const
struct
playlist
*
playlist
)
{
int
current_position
=
playlist_get_current_song
(
playlist
);
int
current_position
=
playlist
->
GetCurrentPosition
();
if
(
current_position
<
0
)
return
false
;
...
...
src/PlaylistQueue.cxx
View file @
52638c68
...
...
@@ -52,7 +52,7 @@ playlist_load_into_queue(const char *uri, struct playlist_provider *source,
if
(
song
==
NULL
)
continue
;
result
=
playlist_append_song
(
dest
,
pc
,
song
,
NULL
);
result
=
dest
->
AppendSong
(
*
pc
,
song
);
song_free
(
song
);
if
(
result
!=
PLAYLIST_RESULT_SUCCESS
)
{
g_free
(
base_uri
);
...
...
src/PlaylistSave.cxx
View file @
52638c68
...
...
@@ -132,8 +132,7 @@ playlist_load_spl(struct playlist *playlist, struct player_control *pc,
for
(
unsigned
i
=
start_index
;
i
<
end_index
;
++
i
)
{
const
auto
&
uri_utf8
=
contents
[
i
];
if
((
playlist_append_uri
(
playlist
,
pc
,
uri_utf8
.
c_str
(),
nullptr
))
!=
PLAYLIST_RESULT_SUCCESS
)
{
if
((
playlist
->
AppendURI
(
*
pc
,
uri_utf8
.
c_str
()))
!=
PLAYLIST_RESULT_SUCCESS
)
{
/* for windows compatibility, convert slashes */
char
*
temp2
=
g_strdup
(
uri_utf8
.
c_str
());
char
*
p
=
temp2
;
...
...
@@ -142,9 +141,10 @@ playlist_load_spl(struct playlist *playlist, struct player_control *pc,
*
p
=
'/'
;
p
++
;
}
if
((
playlist_append_uri
(
playlist
,
pc
,
temp2
,
NULL
))
!=
PLAYLIST_RESULT_SUCCESS
)
{
if
(
playlist
->
AppendURI
(
*
pc
,
temp2
)
!=
PLAYLIST_RESULT_SUCCESS
)
g_warning
(
"can't add file
\"
%s
\"
"
,
temp2
);
}
g_free
(
temp2
);
}
}
...
...
src/PlaylistState.cxx
View file @
52638c68
...
...
@@ -145,26 +145,16 @@ playlist_state_restore(const char *line, TextFile &file,
seek_time
=
atoi
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_TIME
)]));
}
else
if
(
g_str_has_prefix
(
line
,
PLAYLIST_STATE_FILE_REPEAT
))
{
if
(
strcmp
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_REPEAT
)]),
"1"
)
==
0
)
{
playlist_set_repeat
(
playlist
,
pc
,
true
);
}
else
playlist_set_repeat
(
playlist
,
pc
,
false
);
playlist
->
SetRepeat
(
*
pc
,
strcmp
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_REPEAT
)]),
"1"
)
==
0
);
}
else
if
(
g_str_has_prefix
(
line
,
PLAYLIST_STATE_FILE_SINGLE
))
{
if
(
strcmp
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_SINGLE
)]),
"1"
)
==
0
)
{
playlist_set_single
(
playlist
,
pc
,
true
);
}
else
playlist_set_single
(
playlist
,
pc
,
false
);
playlist
->
SetSingle
(
*
pc
,
strcmp
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_SINGLE
)]),
"1"
)
==
0
);
}
else
if
(
g_str_has_prefix
(
line
,
PLAYLIST_STATE_FILE_CONSUME
))
{
if
(
strcmp
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_CONSUME
)]),
"1"
)
==
0
)
{
playlist_set_consume
(
playlist
,
true
);
}
else
playlist_set_consume
(
playlist
,
false
);
playlist
->
SetConsume
(
strcmp
(
&
(
line
[
strlen
(
PLAYLIST_STATE_FILE_CONSUME
)]),
"1"
)
==
0
);
}
else
if
(
g_str_has_prefix
(
line
,
PLAYLIST_STATE_FILE_CROSSFADE
))
{
pc_set_cross_fade
(
pc
,
atoi
(
line
+
strlen
(
PLAYLIST_STATE_FILE_CROSSFADE
)));
...
...
@@ -188,7 +178,7 @@ playlist_state_restore(const char *line, TextFile &file,
}
}
playlist
_set_random
(
playlist
,
pc
,
random_mode
);
playlist
->
SetRandom
(
*
pc
,
random_mode
);
if
(
!
playlist
->
queue
.
IsEmpty
())
{
if
(
!
playlist
->
queue
.
IsValidPosition
(
current
))
...
...
@@ -210,9 +200,9 @@ playlist_state_restore(const char *line, TextFile &file,
if
(
state
==
PLAYER_STATE_STOP
/* && config_option */
)
playlist
->
current
=
current
;
else
if
(
seek_time
==
0
)
playlist
_play
(
playlist
,
pc
,
current
);
playlist
->
PlayPosition
(
*
pc
,
current
);
else
playlist
_seek_song
(
playlist
,
pc
,
current
,
seek_time
);
playlist
->
SeekSongPosition
(
*
pc
,
current
,
seek_time
);
if
(
state
==
PLAYER_STATE_PAUSE
)
pc_pause
(
pc
);
...
...
src/QueueCommands.cxx
View file @
52638c68
...
...
@@ -27,6 +27,7 @@
#include "PlaylistPrint.hxx"
#include "ClientFile.hxx"
#include "ClientInternal.hxx"
#include "Partition.hxx"
#include "protocol/ArgParser.hxx"
#include "protocol/Result.hxx"
#include "ls.hxx"
...
...
@@ -50,10 +51,7 @@ handle_add(Client *client, G_GNUC_UNUSED int argc, char *argv[])
if
(
!
client_allow_file
(
client
,
path
,
&
error
))
return
print_error
(
client
,
error
);
result
=
playlist_append_file
(
&
client
->
playlist
,
client
->
player_control
,
path
,
NULL
);
result
=
client
->
partition
.
AppendFile
(
path
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -64,9 +62,7 @@ handle_add(Client *client, G_GNUC_UNUSED int argc, char *argv[])
return
COMMAND_RETURN_ERROR
;
}
result
=
playlist_append_uri
(
&
client
->
playlist
,
client
->
player_control
,
uri
,
NULL
);
result
=
client
->
partition
.
AppendURI
(
uri
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -91,10 +87,7 @@ handle_addid(Client *client, int argc, char *argv[])
if
(
!
client_allow_file
(
client
,
path
,
&
error
))
return
print_error
(
client
,
error
);
result
=
playlist_append_file
(
&
client
->
playlist
,
client
->
player_control
,
path
,
&
added_id
);
result
=
client
->
partition
.
AppendFile
(
path
,
&
added_id
);
}
else
{
if
(
uri_has_scheme
(
uri
)
&&
!
uri_supported_scheme
(
uri
))
{
command_error
(
client
,
ACK_ERROR_NO_EXIST
,
...
...
@@ -102,9 +95,7 @@ handle_addid(Client *client, int argc, char *argv[])
return
COMMAND_RETURN_ERROR
;
}
result
=
playlist_append_uri
(
&
client
->
playlist
,
client
->
player_control
,
uri
,
&
added_id
);
result
=
client
->
partition
.
AppendURI
(
uri
,
&
added_id
);
}
if
(
result
!=
PLAYLIST_RESULT_SUCCESS
)
...
...
@@ -114,15 +105,11 @@ handle_addid(Client *client, int argc, char *argv[])
unsigned
to
;
if
(
!
check_unsigned
(
client
,
&
to
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_move_id
(
&
client
->
playlist
,
client
->
player_control
,
added_id
,
to
);
result
=
client
->
partition
.
MoveId
(
added_id
,
to
);
if
(
result
!=
PLAYLIST_RESULT_SUCCESS
)
{
enum
command_return
ret
=
print_playlist_result
(
client
,
result
);
playlist_delete_id
(
&
client
->
playlist
,
client
->
player_control
,
added_id
);
client
->
partition
.
DeleteId
(
added_id
);
return
ret
;
}
}
...
...
@@ -135,14 +122,11 @@ enum command_return
handle_delete
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
char
*
argv
[])
{
unsigned
start
,
end
;
enum
playlist_result
result
;
if
(
!
check_range
(
client
,
&
start
,
&
end
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_delete_range
(
&
client
->
playlist
,
client
->
player_control
,
start
,
end
);
enum
playlist_result
result
=
client
->
partition
.
DeleteRange
(
start
,
end
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -150,13 +134,11 @@ enum command_return
handle_deleteid
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
char
*
argv
[])
{
unsigned
id
;
enum
playlist_result
result
;
if
(
!
check_unsigned
(
client
,
&
id
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_delete_id
(
&
client
->
playlist
,
client
->
player_control
,
id
);
enum
playlist_result
result
=
client
->
partition
.
DeleteId
(
id
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -176,8 +158,7 @@ handle_shuffle(G_GNUC_UNUSED Client *client,
if
(
argc
==
2
&&
!
check_range
(
client
,
&
start
,
&
end
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
playlist_shuffle
(
&
client
->
playlist
,
client
->
player_control
,
start
,
end
);
client
->
partition
.
Shuffle
(
start
,
end
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -185,7 +166,7 @@ enum command_return
handle_clear
(
G_GNUC_UNUSED
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
G_GNUC_UNUSED
char
*
argv
[])
{
playlist_clear
(
&
client
->
playlist
,
client
->
player_control
);
client
->
partition
.
ClearQueue
(
);
return
COMMAND_RETURN_OK
;
}
...
...
@@ -296,9 +277,8 @@ handle_prio(Client *client, int argc, char *argv[])
return
COMMAND_RETURN_ERROR
;
enum
playlist_result
result
=
playlist_set_priority
(
&
client
->
playlist
,
client
->
player_control
,
start_position
,
end_position
,
client
->
partition
.
SetPriorityRange
(
start_position
,
end_position
,
priority
);
if
(
result
!=
PLAYLIST_RESULT_SUCCESS
)
return
print_playlist_result
(
client
,
result
);
...
...
@@ -327,9 +307,7 @@ handle_prioid(Client *client, int argc, char *argv[])
return
COMMAND_RETURN_ERROR
;
enum
playlist_result
result
=
playlist_set_priority_id
(
&
client
->
playlist
,
client
->
player_control
,
song_id
,
priority
);
client
->
partition
.
SetPriorityId
(
song_id
,
priority
);
if
(
result
!=
PLAYLIST_RESULT_SUCCESS
)
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -342,14 +320,14 @@ handle_move(Client *client, G_GNUC_UNUSED int argc, char *argv[])
{
unsigned
start
,
end
;
int
to
;
enum
playlist_result
result
;
if
(
!
check_range
(
client
,
&
start
,
&
end
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
if
(
!
check_int
(
client
,
&
to
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_move_range
(
&
client
->
playlist
,
client
->
player_control
,
start
,
end
,
to
);
enum
playlist_result
result
=
client
->
partition
.
MoveRange
(
start
,
end
,
to
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -358,14 +336,12 @@ handle_moveid(Client *client, G_GNUC_UNUSED int argc, char *argv[])
{
unsigned
id
;
int
to
;
enum
playlist_result
result
;
if
(
!
check_unsigned
(
client
,
&
id
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
if
(
!
check_int
(
client
,
&
to
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_move_id
(
&
client
->
playlist
,
client
->
player_control
,
id
,
to
);
enum
playlist_result
result
=
client
->
partition
.
MoveId
(
id
,
to
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -373,14 +349,14 @@ enum command_return
handle_swap
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
char
*
argv
[])
{
unsigned
song1
,
song2
;
enum
playlist_result
result
;
if
(
!
check_unsigned
(
client
,
&
song1
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
if
(
!
check_unsigned
(
client
,
&
song2
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_swap_songs
(
&
client
->
playlist
,
client
->
player_control
,
song1
,
song2
);
enum
playlist_result
result
=
client
->
partition
.
SwapPositions
(
song1
,
song2
);
return
print_playlist_result
(
client
,
result
);
}
...
...
@@ -388,14 +364,12 @@ enum command_return
handle_swapid
(
Client
*
client
,
G_GNUC_UNUSED
int
argc
,
char
*
argv
[])
{
unsigned
id1
,
id2
;
enum
playlist_result
result
;
if
(
!
check_unsigned
(
client
,
&
id1
,
argv
[
1
]))
return
COMMAND_RETURN_ERROR
;
if
(
!
check_unsigned
(
client
,
&
id2
,
argv
[
2
]))
return
COMMAND_RETURN_ERROR
;
result
=
playlist_swap_songs_id
(
&
client
->
playlist
,
client
->
player_control
,
id1
,
id2
);
enum
playlist_result
result
=
client
->
partition
.
SwapIds
(
id1
,
id2
);
return
print_playlist_result
(
client
,
result
);
}
src/UpdateRemove.cxx
View file @
52638c68
...
...
@@ -64,9 +64,7 @@ song_remove_event(void)
sticker_song_delete
(
removed_song
);
#endif
playlist_delete_song
(
&
global_partition
->
playlist
,
&
global_partition
->
pc
,
removed_song
);
global_partition
->
DeleteSong
(
*
removed_song
);
/* clear "removed_song" and send signal to update thread */
g_mutex_lock
(
remove_mutex
);
...
...
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