PaylistTag: use class TagBuilder

This commit is contained in:
Max Kellermann 2013-12-03 12:56:36 +01:00
parent c36af35730
commit 9f4e96fdfa
5 changed files with 54 additions and 44 deletions

View File

@ -28,6 +28,7 @@
#include "PlaylistError.hxx" #include "PlaylistError.hxx"
#include "Song.hxx" #include "Song.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/TagBuilder.hxx"
#include "util/Error.hxx" #include "util/Error.hxx"
bool bool
@ -48,9 +49,15 @@ playlist::AddSongIdTag(unsigned id, TagType tag_type, const char *value,
return false; return false;
} }
if (song.tag == nullptr) TagBuilder tag;
song.tag = new Tag(); if (song.tag != nullptr) {
song.tag->AddItem(tag_type, value); tag = std::move(*song.tag);
delete song.tag;
}
tag.AddItem(tag_type, value);
song.tag = tag.Commit();
queue.ModifyAtPosition(position); queue.ModifyAtPosition(position);
OnModified(); OnModified();
return true; return true;
@ -77,10 +84,15 @@ playlist::ClearSongIdTag(unsigned id, TagType tag_type,
if (song.tag == nullptr) if (song.tag == nullptr)
return true; return true;
TagBuilder tag(std::move(*song.tag));
delete song.tag;
if (tag_type == TAG_NUM_OF_ITEM_TYPES) if (tag_type == TAG_NUM_OF_ITEM_TYPES)
song.tag->RemoveAll(); tag.RemoveAll();
else else
song.tag->RemoveType(tag_type); tag.RemoveType(tag_type);
song.tag = tag.Commit();
queue.ModifyAtPosition(position); queue.ModifyAtPosition(position);
OnModified(); OnModified();
return true; return true;

View File

@ -187,23 +187,3 @@ Tag::AddItem(TagType type, const char *value)
{ {
AddItem(type, value, strlen(value)); AddItem(type, value, strlen(value));
} }
void
Tag::RemoveType(TagType type)
{
auto dest = items, src = items, end = items + num_items;
tag_pool_lock.lock();
while (src != end) {
TagItem *item = *src++;
if (item->type == type)
/* remove it */
tag_pool_put_item(item);
else
/* keep it */
*dest++ = item;
}
tag_pool_lock.unlock();
num_items = dest - items;
}

View File

@ -121,18 +121,6 @@ struct Tag {
*/ */
void AddItem(TagType type, const char *value); void AddItem(TagType type, const char *value);
/**
* Removes all tag items.
*/
void RemoveAll() {
num_items = 0;
}
/**
* Removes all tag items of the specified type.
*/
void RemoveType(TagType type);
/** /**
* Merges the data from two tags. If both tags share data for the * Merges the data from two tags. If both tags share data for the
* same TagType, only data from "add" is used. * same TagType, only data from "add" is used.

View File

@ -108,13 +108,7 @@ TagBuilder::Clear()
{ {
time = -1; time = -1;
has_playlist = false; has_playlist = false;
RemoveAll();
tag_pool_lock.lock();
for (auto i : items)
tag_pool_put_item(i);
tag_pool_lock.unlock();
items.clear();
} }
void void
@ -216,3 +210,29 @@ TagBuilder::AddItem(TagType type, const char *value)
AddItem(type, value, strlen(value)); AddItem(type, value, strlen(value));
} }
void
TagBuilder::RemoveAll()
{
tag_pool_lock.lock();
for (auto i : items)
tag_pool_put_item(i);
tag_pool_lock.unlock();
items.clear();
}
void
TagBuilder::RemoveType(TagType type)
{
const auto begin = items.begin(), end = items.end();
items.erase(std::remove_if(begin, end,
[type](TagItem *item) {
if (item->type != type)
return false;
tag_pool_put_item(item);
return true;
}),
end);
}

View File

@ -147,6 +147,16 @@ public:
gcc_nonnull_all gcc_nonnull_all
void AddItem(TagType type, const char *value); void AddItem(TagType type, const char *value);
/**
* Removes all tag items.
*/
void RemoveAll();
/**
* Removes all tag items of the specified type.
*/
void RemoveType(TagType type);
private: private:
gcc_nonnull_all gcc_nonnull_all
void AddItemInternal(TagType type, const char *value, size_t length); void AddItemInternal(TagType type, const char *value, size_t length);