ocarina/core/deck.cpp

236 lines
4.0 KiB
C++

/**
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/deck.h>
#include <core/file.h>
#include <core/library.h>
class RecentQueue : public Queue
{
public:
RecentQueue() : Queue(Q_ENABLED | Q_REPEAT | Q_NO_SORT) {}
unsigned int add(Track *track)
{
del(track);
_cur = 0;
return _add_at(track, 0);
}
};
static std::list<TempQueue> queue_deck;
static RecentQueue recent_queue;
static File deck_file("deck", 1);
TempQueue :: TempQueue() {}
TempQueue :: TempQueue(bool random)
: Queue(Q_ENABLED | (random ? Q_RANDOM : 0)) {}
void TempQueue :: set_flag(queue_flags flag)
{
Queue :: set_flag(flag);
deck :: write();
}
void TempQueue :: unset_flag(queue_flags flag)
{
Queue :: unset_flag(flag);
deck :: write();
}
unsigned int TempQueue :: add(Track *track)
{
unsigned int res = Queue :: add(track);
deck :: write();
return res;
}
void TempQueue :: del(Track *track)
{
Queue :: del(track);
deck :: write();
}
void TempQueue :: del(unsigned int id)
{
Queue :: del(id);
deck :: write();
}
void TempQueue :: sort(sort_t field, bool ascending)
{
Queue :: sort(field, ascending);
deck :: write();
}
static void upgrade_v0()
{
int random, ascending;
unsigned int num, field;
Queue *library = library :: get_queue();
deck_file >> random >> num;
if (random)
library->set_flag(Q_RANDOM);
for (unsigned int i = 0; i < num; i++) {
deck_file >> field >> ascending;
library->sort((sort_t)field, (i == 0) ? true : false);
if (!ascending)
library->sort((sort_t)field, false);
}
}
void deck :: init()
{
unsigned int num;
bool upgraded = false;
std::list<TempQueue>::iterator it;
if (!deck_file.open(OPEN_READ))
return;
if (deck_file.get_version() == 0) {
upgrade_v0();
upgraded = true;
}
deck_file >> num;
queue_deck.resize(num);
for (it = queue_deck.begin(); it != queue_deck.end(); it++)
it->read(deck_file);
deck_file.close();
if (upgraded)
deck :: write();
}
void deck :: write()
{
std::list<TempQueue>::iterator it;
if (!deck_file.open(OPEN_WRITE))
return;
deck_file << queue_deck.size() << std :: endl;
for (it = queue_deck.begin(); it != queue_deck.end(); it++) {
it->write(deck_file);
deck_file << std::endl;
}
deck_file.close();
}
Queue *deck :: create(bool random)
{
queue_deck.push_back(TempQueue(random));
return &queue_deck.back();
}
static void _destroy(std::list<TempQueue>::iterator &it)
{
queue_deck.erase(it);
deck :: write();
}
void deck :: destroy(Queue *queue)
{
std::list<TempQueue>::iterator it;
for (it = queue_deck.begin(); it != queue_deck.end(); it++) {
if (&(*it) == queue) {
_destroy(it);
return;
}
}
}
void deck :: move(Queue *queue, unsigned int index)
{
unsigned int old_pos = deck :: index(queue);
std::list<TempQueue>::iterator it_old = queue_deck.begin();
std::list<TempQueue>::iterator it_new = queue_deck.begin();
for (unsigned int i = 0; i < queue_deck.size(); i++) {
if (i < old_pos)
it_old++;
if (i < index)
it_new++;
}
if (index > old_pos)
it_new++;
queue_deck.splice(it_new, queue_deck, it_old);
write();
}
unsigned int deck :: index(Queue *queue)
{
unsigned int i = 0;
std::list<TempQueue>::iterator it;
for (it = queue_deck.begin(); it != queue_deck.end(); it++) {
if (&(*it) == queue)
return i;
i++;
}
return queue_deck.size();
}
Queue *deck :: get(unsigned int index)
{
std::list<TempQueue>::iterator it;
for (it = queue_deck.begin(); it != queue_deck.end(); it++) {
if (index == 0)
return &(*it);
index--;
}
return NULL;
}
Track *deck :: next()
{
Track *track = NULL;
std::list<TempQueue>::iterator it;
for (it = queue_deck.begin(); it != queue_deck.end(); it++) {
if (it->has_flag(Q_ENABLED) == false)
continue;
track = it->next();
if (it->size() == 0)
_destroy(it);
break;
}
if (!track)
track = library :: get_queue()->next();
if (track)
recent_queue.add(track);
return track;
}
Track *deck :: prev()
{
return recent_queue.next();
}
std::list<TempQueue> &deck :: get_queues()
{
return queue_deck;
}
Queue *deck :: get_queue()
{
return &recent_queue;
}