track: Implement comparison function

Used later for sorting queues.

Signed-off-by: Anna Schumaker <anna@ocarinaproject.net>
This commit is contained in:
Anna Schumaker 2014-03-26 20:14:00 -04:00 committed by Anna Schumaker
parent c15c5149bc
commit ac338c5704
4 changed files with 137 additions and 8 deletions

9
DESIGN
View File

@ -848,10 +848,13 @@ Track Tag:
Combine library->path and filepath to find the full path to
the audio file.
bool Track :: less_than(Track *rhs, sort_t field);
int Track :: less_than(Track *rhs, sort_t field);
Compare the requested field for this Track instance to the same
field in the provided track. Return true if we find that this
instance is less than rhs and false otherwise.
field in the provided track.
Return -1 if this < rhs.
Return 0 if this == rhs.
Return 1 if this > rhs.

View File

@ -104,7 +104,7 @@ public:
void tag();
const std::string path() const;
bool less_than(Track *, sort_t);
int less_than(Track *, sort_t);
};

View File

@ -246,9 +246,60 @@ const std::string Track :: path() const
return library->root_path + "/" + filepath;
}
bool Track :: less_than(Track *rhs, sort_t field)
/*
* Returns:
* 0: lhs == rhs
* < 0: lhs < rhs, or rhs is empty
* > 0: lhs > rhs, or lhs is empty
*/
static inline int compare_string(const std::string &a, const std::string &b)
{
return false;
if (a.size() == 0)
return 1;
else if (b.size() == 0)
return -1;
return a.compare(b);
}
static inline int compare_uint(unsigned int a, unsigned int b)
{
if (a == b)
return 0;
if (a < b)
return -1;
return 1;
}
int Track :: less_than(Track *rhs, sort_t field)
{
int ret;
switch (field) {
case SORT_ARTIST:
return compare_string(artist->lower, rhs->artist->lower);
case SORT_ALBUM:
return compare_string(album->lower, rhs->album->lower);
case SORT_COUNT:
return compare_uint(play_count, rhs->play_count);
case SORT_GENRE:
return compare_string(genre->lower, rhs->genre->lower);
case SORT_LENGTH:
return compare_uint(length, rhs->length);
case SORT_PLAYED:
ret = compare_uint(last_year, rhs->last_year);
if (ret == 0) {
ret = compare_uint(last_month, rhs->last_month);
if (ret == 0)
ret = compare_uint(last_day, rhs->last_day);
}
return ret;
case SORT_TITLE:
return compare_string(title_lower, rhs->title_lower);
case SORT_TRACK:
return compare_uint(track, rhs->track);
case SORT_YEAR:
return compare_uint(album->year, rhs->album->year);
}
return 0;
}

View File

@ -185,7 +185,7 @@ void track_test_lenstrs(const std::string &file, const std::string &expected,
test_results(track.length_str == expected, line);
}
void track_test_extras(Library *library)
void track_test_lenstrs(Library *library)
{
track_test_lenstrs("Music/1.ogg", "0:01", library, __LINE__);
track_test_lenstrs("Music/10.ogg", "0:10", library, __LINE__);
@ -196,11 +196,86 @@ void track_test_extras(Library *library)
track_test_lenstrs("Music/666.ogg", "11:06", library, __LINE__);
}
void test_track_sorting()
{
Track track1, track2;
Artist artist1("a"), artist2("b");
Album album1("a", 2000), album2("b", 2014);
Genre genre1("a"), genre2("b");
track1.artist = &artist1;
track1.album = &album1;
track1.genre = &genre1;
track1.length = 10;
track1.play_count = 0;
track1.last_year = 2013;
track1.title_lower = "a";
track1.track = 1;
track2.artist = &artist2;
track2.album = &album2;
track2.genre = &genre2;
track2.length = 20;
track2.play_count = 1;
track2.last_year = 2014;
track2.title_lower = "b";
track2.track = 2;
test_results(track1.less_than(&track1, SORT_ARTIST) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_ARTIST) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_ARTIST) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_ALBUM) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_ALBUM) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_ALBUM) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_GENRE) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_GENRE) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_GENRE) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_LENGTH) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_LENGTH) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_LENGTH) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_PLAYED) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_PLAYED) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_PLAYED) > 0, __LINE__);
track1.last_year = 2014;
track1.last_month = 3;
track2.last_month = 4;
test_results(track1.less_than(&track1, SORT_PLAYED) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_PLAYED) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_PLAYED) > 0, __LINE__);
track1.last_month = 4;
track1.last_day = 10;
track2.last_day = 11;
test_results(track1.less_than(&track1, SORT_PLAYED) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_PLAYED) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_PLAYED) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_TITLE) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_TITLE) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_TITLE) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_TRACK) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_TRACK) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_TRACK) > 0, __LINE__);
test_results(track1.less_than(&track1, SORT_YEAR) == 0, __LINE__);
test_results(track1.less_than(&track2, SORT_YEAR) < 0, __LINE__);
test_results(track2.less_than(&track1, SORT_YEAR) > 0, __LINE__);
}
void track_test()
{
Library *library = tagdb :: add_library("Music");
track_test_basics(library);
track_test_extras(library);
track_test_lenstrs(library);
test_track_sorting();
}