ocarina/lib/deck.cpp

233 lines
5.0 KiB
C++

/*
* Copyright 2013 (c) Anna Schumaker.
*/
#include <callback.h>
#include <deck.h>
#include <error.h>
#include <file.h>
#include <print.h>
#include <list>
static std::list<Queue> playqueue_deck;
static Queue library_playqueue(Q_ENABLED);
static File deck_file("deck");
static void add_library_track(unsigned int id)
{
library_playqueue.add(tagdb :: lookup(id));
}
static void del_library_track(unsigned int id)
{
library_playqueue.del(tagdb :: lookup(id));
}
static void change_library_track(unsigned int id)
{
library_playqueue.updated(tagdb :: lookup(id));
}
void deck :: init()
{
library_playqueue.set_flag(Q_REPEAT);
library_playqueue.set_flag(Q_DISABLE_CHANGED_SIZE);
library_playqueue.add_sort(SORT_ARTIST);
library_playqueue.add_sort(SORT_YEAR);
library_playqueue.add_sort(SORT_TRACK);
read();
get_callbacks()->on_playlist_ban = del_library_track;
get_callbacks()->on_playlist_unban = add_library_track;
get_callbacks()->on_library_track_add = add_library_track;
get_callbacks()->on_library_track_del = del_library_track;
get_callbacks()->on_library_track_updated = change_library_track;
get_callbacks()->on_queue_changed = write;
}
void deck :: read()
{
unsigned int num;
int random;
unsigned int field;
bool ascending;
std::list<Queue>::iterator it;
if (!deck_file.exists())
return;
deck_file.open(OPEN_READ);
deck_file >> random >> num;
library_playqueue.force_clear_sort();
for (unsigned int i = 0; i < num; i++) {
deck_file >> field >> ascending;
if (i == 0)
library_playqueue.reset_sort((sort_t)field, ascending);
else
library_playqueue.add_sort((sort_t)field, ascending);
}
deck_file >> num;
if (random)
library_playqueue.set_flag(Q_RANDOM);
playqueue_deck.resize(num);
num = 0;
for (it = playqueue_deck.begin(); it != playqueue_deck.end(); it++) {
it->read(deck_file);
get_callbacks()->on_pq_created(&(*it), num);
num++;
}
deck_file.close();
}
void deck :: write()
{
std::list<Queue>::iterator it;
std::list<sort_info>::iterator st;
std::list<sort_info> sort_order;
deck_file.open(OPEN_WRITE);
/* Save library playqueue */
sort_order = library_playqueue.get_sort_order();
deck_file << library_playqueue.has_flag(Q_RANDOM) << " ";
deck_file << sort_order.size() << " ";
for (st = sort_order.begin(); st != sort_order.end(); st++)
deck_file << st->field << " " << st->ascending << " ";
deck_file << playqueue_deck.size() << std :: endl;
for (it = playqueue_deck.begin(); it != playqueue_deck.end(); it++) {
it->write(deck_file);
deck_file << std::endl;
}
deck_file.close();
}
Queue *deck :: create(bool random)
{
Queue *pq;
playqueue_deck.push_back(Queue(Q_ENABLED));
pq = &playqueue_deck.back();
if (random == true)
pq->set_flag(Q_RANDOM);
get_callbacks()->on_pq_created(pq, playqueue_deck.size() - 1);
return pq;
}
void deck :: remove(unsigned int id)
{
std::list<Queue>::iterator it = playqueue_deck.begin();
for (unsigned int i = 0; i < id; i++)
it++;
get_callbacks()->on_pq_removed(&(*it));
playqueue_deck.erase(it);
write();
}
Queue *deck :: get(unsigned int id)
{
std::list<Queue>::iterator it = playqueue_deck.begin();
for (unsigned int i = 0; i < id; i++)
it++;
return &(*it);
}
unsigned int deck :: size()
{
return playqueue_deck.size();
}
void deck :: move(unsigned int old_pos, unsigned int new_pos)
{
std::list<Queue>::iterator it_old = playqueue_deck.begin();
std::list<Queue>::iterator it_new = playqueue_deck.begin();
for (unsigned int i = 0; i < playqueue_deck.size(); i++) {
if (i < old_pos)
it_old++;
if (i < new_pos)
it_new++;
}
if (new_pos > old_pos)
it_new++;
playqueue_deck.splice(it_new, playqueue_deck, it_old);
}
void deck :: move(Queue *pq, unsigned int new_pos)
{
unsigned int old_pos = 0;
std::list<Queue>::iterator it_old = playqueue_deck.begin();
std::list<Queue>::iterator it_new = playqueue_deck.begin();
for (unsigned int i = 0; i < playqueue_deck.size(); i++) {
if (&(*it_old) != pq) {
it_old++;
old_pos++;
}
if (i < new_pos)
it_new++;
}
if (new_pos > old_pos)
it_new++;
playqueue_deck.splice(it_new, playqueue_deck, it_old);
}
Track *deck :: next()
{
Track *track;
std::list<Queue>::iterator it;
for (it = playqueue_deck.begin(); it != playqueue_deck.end(); it++) {
if (it->has_flag(Q_ENABLED)) {
if (it->size() == 0) {
playqueue_deck.erase(it);
get_callbacks()->on_pq_removed(&(*it));
} else {
track = it->next();
if (it->size() == 0) {
playqueue_deck.erase(it);
get_callbacks()->on_pq_removed(&(*it));
}
}
write();
return track;
}
}
return library_playqueue.next();
}
Queue *deck :: get_library_pq()
{
return &library_playqueue;
}
#ifdef CONFIG_TEST
static void no_op() {}
void deck :: reset()
{
get_callbacks()->on_queue_changed = no_op;
playqueue_deck.clear();
library_playqueue.reset();
}
void deck :: print_info()
{
unsigned int i = 0;
std::list<Queue>::iterator it;
for (it = playqueue_deck.begin(); it != playqueue_deck.end(); it++) {
print("deck[%u] = Queue { size = %u, flags = %u }\n",
i, it->size());
i++;
}
}
#endif /* CONFIG_TEST */