/* * Copyright 2013 (c) Anna Schumaker. */ #include #include #include #include #include static struct file tempq_file = FILE_INIT("deck", 1, 1); static struct queue_ops *tempq_ops = NULL; static GSList *tempq_list; static struct file tempq_file; static struct queue *__tempq_alloc(unsigned int flags) { struct queue *queue = g_malloc(sizeof(struct queue)); flags = flags | Q_SAVE_FLAGS | Q_SAVE_SORT; tempq_list = g_slist_append(tempq_list, queue); queue_init(queue, flags, tempq_ops, NULL); return queue; } static void __tempq_free(struct queue *queue) { tempq_list = g_slist_remove(tempq_list, queue); queue_deinit(queue); g_free(queue); } static void __tempq_read_queue() { struct queue *queue; unsigned int flags; file_readf(&tempq_file, "%u", &flags); queue = __tempq_alloc(flags); queue_load_tracks(queue, &tempq_file); } static void __tempq_write_queue(struct queue *queue) { file_writef(&tempq_file, "%u ", queue->q_flags); queue_save_tracks(queue, &tempq_file); file_writef(&tempq_file, "\n"); } static bool __tempq_init_idle(void *data) { unsigned int num, i; if (!file_open(&tempq_file, OPEN_READ)) return true; file_readf(&tempq_file, "%u", &num); for (i = 0; i < num; i++) __tempq_read_queue(); file_close(&tempq_file); return true; } void tempq_init(struct queue_ops *ops) { tempq_ops = ops; idle_schedule(IDLE_SYNC, __tempq_init_idle, NULL); } void tempq_deinit() { while (tempq_list) __tempq_free((struct queue *)tempq_list->data); } void tempq_save(struct queue *queue, enum queue_flags flag) { GSList *cur; if (!file_open(&tempq_file, OPEN_WRITE)) return; file_writef(&tempq_file, "%zu\n", g_slist_length(tempq_list)); for (cur = tempq_list; cur; cur = g_slist_next(cur)) __tempq_write_queue((struct queue *)cur->data); file_close(&tempq_file); } struct queue *tempq_alloc(unsigned int flags) { struct queue *queue = __tempq_alloc(Q_ENABLED | flags); tempq_save(queue, Q_ENABLED); return queue; } void tempq_free(struct queue *queue) { __tempq_free(queue); tempq_save(NULL, Q_ENABLED); } struct queue *tempq_get(unsigned int index) { return (struct queue *)g_slist_nth_data(tempq_list, index); } unsigned int tempq_index(struct queue *queue) { return g_slist_index(tempq_list, queue); } void tempq_move(struct queue *queue, unsigned int index) { GSList *cur = g_slist_find(tempq_list, queue); GSList *nth = g_slist_nth(tempq_list, index); if (cur && nth && (cur != nth)) { tempq_list = g_slist_remove(tempq_list, queue); tempq_list = g_slist_insert_before(tempq_list, nth, queue); tempq_save(queue, Q_ENABLED); } } struct track *tempq_next() { struct track *track = NULL; struct queue *queue = NULL; GSList *cur; for (cur = tempq_list; cur; cur = g_slist_next(cur)) { queue = (struct queue *)cur->data; if (queue_has_flag(queue, Q_ENABLED)) { track = queue_next(queue); break; } } if (queue && queue_size(queue) == 0) tempq_free(queue); return track; } unsigned int tempq_count() { return g_slist_length(tempq_list); } void tempq_updated(struct track *track) { GSList *cur; for (cur = tempq_list; cur; cur = g_slist_next(cur)) queue_updated((struct queue *)cur->data, track); }