Skip to content

Commit

Permalink
Implement playlist shuffle.
Browse files Browse the repository at this point in the history
    - Triggered by `script-message jftui-playlist-shuffle`.
    - Does not touch currently playing item.
    - Starts addressing #17.
  • Loading branch information
Aanok committed Feb 20, 2021
1 parent 3786d0a commit a6e06c9
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 21 deletions.
64 changes: 45 additions & 19 deletions src/disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ void jf_disk_refresh()
}


////////// PAYLOAD ///////////
void jf_disk_payload_add_item(const jf_menu_item *item)
{
if (item == NULL) return;
Expand All @@ -192,25 +193,6 @@ jf_menu_item *jf_disk_payload_get_item(const size_t n)
}


const char *jf_disk_playlist_get_item_name(const size_t n)
{

if (n == 0 || n > s_playlist.count) {
return "Warning: requesting item out of bounds. This is a bug.";
}

jf_disk_align_to(&s_playlist, n);
assert(fseek(s_playlist.body,
// let him who hath understanding reckon the number of the beast!
sizeof(jf_item_type) + sizeof(((jf_menu_item *)666)->id),
SEEK_CUR) == 0);

jf_disk_read_to_null_to_buffer(&s_playlist);

return (const char *)s_buffer->buf;
}


jf_item_type jf_disk_payload_get_type(const size_t n)
{
jf_item_type item_type;
Expand All @@ -232,8 +214,10 @@ size_t jf_disk_payload_item_count()
{
return s_payload.count;
}
//////////////////////////////


////////// PLAYLIST ///////////
void jf_disk_playlist_add_item(const jf_menu_item *item)
{
if (item == NULL || JF_ITEM_TYPE_IS_FOLDER(item->type)) return;
Expand All @@ -247,6 +231,47 @@ jf_menu_item *jf_disk_playlist_get_item(const size_t n)
}


const char *jf_disk_playlist_get_item_name(const size_t n)
{

if (n == 0 || n > s_playlist.count) {
return "Warning: requesting item out of bounds. This is a bug.";
}

jf_disk_align_to(&s_playlist, n);
assert(fseek(s_playlist.body,
// let him who hath understanding reckon the number of the beast!
sizeof(jf_item_type) + sizeof(((jf_menu_item *)666)->id),
SEEK_CUR) == 0);

jf_disk_read_to_null_to_buffer(&s_playlist);

return (const char *)s_buffer->buf;
}


void jf_disk_playlist_swap_items(const size_t a, const size_t b)
{
long old_a_value;
long old_b_value;

if (a > s_playlist.count || b > s_playlist.count || a == b) return;

// read offset a
assert(fseek(s_playlist.header, (long)((a - 1) * sizeof(long)), SEEK_SET) == 0);
assert(fread(&old_a_value, sizeof(long), 1, s_playlist.header) == 1);
// read offset b
assert(fseek(s_playlist.header, (long)((b - 1) * sizeof(long)), SEEK_SET) == 0);
assert(fread(&old_b_value, sizeof(long), 1, s_playlist.header) == 1);
// overwrite b
assert(fseek(s_playlist.header, (long)((b - 1) * sizeof(long)), SEEK_SET) == 0);
assert(fwrite(&old_a_value, sizeof(long), 1, s_playlist.header) == 1);
// overwrite a
assert(fseek(s_playlist.header, (long)((a - 1) * sizeof(long)), SEEK_SET) == 0);
assert(fwrite(&old_b_value, sizeof(long), 1, s_playlist.header) == 1);
}


void jf_disk_playlist_replace_item(const size_t n, const jf_menu_item *item)
{
long starting_body_offset;
Expand All @@ -268,3 +293,4 @@ size_t jf_disk_playlist_item_count()
{
return s_playlist.count;
}
///////////////////////////////
1 change: 1 addition & 0 deletions src/disk.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ size_t jf_disk_payload_item_count(void);

void jf_disk_playlist_add_item(const jf_menu_item *item);
void jf_disk_playlist_replace_item(const size_t n, const jf_menu_item *item);
void jf_disk_playlist_swap_items(const size_t a, const size_t b);
jf_menu_item *jf_disk_playlist_get_item(const size_t n);
const char *jf_disk_playlist_get_item_name(const size_t n);
size_t jf_disk_playlist_item_count(void);
Expand Down
5 changes: 5 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <errno.h>
#include <locale.h>
#include <assert.h>
#include <time.h>
#include <mpv/client.h>
#include <yajl/yajl_version.h>

Expand Down Expand Up @@ -97,6 +98,9 @@ static inline void jf_mpv_event_dispatch(const mpv_event *event)
jf_term_clear_bottom(NULL);
jf_playback_print_playlist(0);
JF_MPV_ASSERT(mpv_set_property(g_mpv_ctx, "terminal", MPV_FORMAT_FLAG, &mpv_flag_yes));
} else if (strcmp(((mpv_event_client_message *)event->data)->args[0],
"jftui-playlist-shuffle") == 0) {
jf_playback_shuffle_playlist();
}
}
break;
Expand Down Expand Up @@ -272,6 +276,7 @@ int main(int argc, char *argv[])
// SETUP GLOBAL STATE
g_state = (jf_global_state){ 0 };
assert((g_state.session_id = jf_generate_random_id(0)) != NULL);
srandom((unsigned)time(NULL));
/////////////////////


Expand Down
17 changes: 17 additions & 0 deletions src/playback.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,23 @@ void jf_playback_end()
}


void jf_playback_shuffle_playlist()
{
size_t pos = g_state.playlist_position - 1;
size_t item_count_no_curr = jf_disk_playlist_item_count() - 1;
size_t i;
size_t j;

for (i = 0; i < item_count_no_curr - 1; i++) {
if (i == pos) continue;
if ((j = (size_t)random() % (item_count_no_curr - i - 1) + i + 1) >= pos) {
j++;
}
jf_disk_playlist_swap_items(i + 1, j + 1);
}
}


static void jf_playback_playlist_window(size_t window_size, size_t window[2])
{
size_t pos = g_state.playlist_position;
Expand Down
2 changes: 2 additions & 0 deletions src/playback.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ void jf_playback_play_video(const jf_menu_item *item);
bool jf_playback_next(void);
bool jf_playback_previous(void);
void jf_playback_end(void);
// won't move item currently playing
void jf_playback_shuffle_playlist(void);

// Will print part or the entirety of the current jftui playback playlist to
// stdout.
Expand Down
3 changes: 1 addition & 2 deletions src/shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,9 +378,8 @@ char *jf_generate_random_id(size_t len)

assert((rand_id = malloc(len + 1)) != NULL);
rand_id[len] = '\0';
srand((unsigned int)time(NULL));
for (; len > 0; len--) {
rand_id[len - 1] = '0' + rand() % 10;
rand_id[len - 1] = '0' + random() % 10;
}
return rand_id;
}
Expand Down

0 comments on commit a6e06c9

Please sign in to comment.