ocarina/core/tempq.c

151 lines
3.2 KiB
C

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/collection.h>
#include <core/file.h>
#include <core/history.h>
#include <core/tempq.h>
#include <glib.h>
static GSList *tempq_list;
static struct file tempq_file;
static struct queue *__tempq_alloc(struct queue_ops *ops, unsigned int flags)
{
struct queue *queue = g_malloc(sizeof(struct queue));
tempq_list = g_slist_append(tempq_list, queue);
queue_init(queue, flags | Q_SAVE_FLAGS | Q_SAVE_SORT, ops);
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_ops *ops)
{
unsigned int flags, count, i, track;
struct queue *queue;
file_readf(&tempq_file, "%u %u", &flags, &count);
queue = __tempq_alloc(ops, flags);
for (i = 0; i < count; i++) {
file_readf(&tempq_file, "%u", &track);
queue_add(queue, track_get(track));
}
}
static void __tempq_write_queue(struct queue *queue)
{
struct _q_iter it;
struct track *track;
file_writef(&tempq_file, "%u %u", queue->q_flags, queue_size(queue));
_q_for_each(&queue->q_tracks, &it) {
track = (struct track *)_q_iter_val(&it);
file_writef(&tempq_file, " %u", track->tr_dbe.dbe_index);
}
file_writef(&tempq_file, "\n");
}
void tempq_init(struct queue_ops *ops)
{
unsigned int num, i;
file_init(&tempq_file, "deck", 1);
if (!file_open(&tempq_file, OPEN_READ))
return;
if (file_version(&tempq_file) < 1)
goto out;
file_readf(&tempq_file, "%u", &num);
for (i = 0; i < num; i++)
__tempq_read_queue(ops);
out:
file_close(&tempq_file);
}
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(struct queue_ops *ops, unsigned int flags)
{
struct queue *queue = __tempq_alloc(ops, 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);
}