/** * Copyright 2013 (c) Anna Schumaker. */ #include #include #include 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 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::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::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::iterator &it) { queue_deck.erase(it); deck :: write(); } void deck :: destroy(Queue *queue) { std::list::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::iterator it_old = queue_deck.begin(); std::list::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::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::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::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 &deck :: get_queues() { return queue_deck; } Queue *deck :: get_queue() { return &recent_queue; }