On Wed, 4 Oct 2000, Chris Kuklewicz wrote:
Hmm. This is going to be overly ""ed. Oh well.
On Wed, Oct 04, 2000 at 02:40:10PM -0500, David A. Walker wrote:
After pondering the searching issue some more, I came up with a function
prototype that will (hopefully) address everyone's needs:
int FindSong(char *pattern, int type, int casematters)
And the returned int is the index of the first or next matching song?
As this would be a C++ method, what new or existing object would own it?
I was planning on makeing this part of PlaylistManager. The returned int
would be the index of the song, -1 for no match, and -2 for malformed
arguments. These return values could be enum'ed as SEARCH_NOMATCH and
SEARCH_BADPATTERN or something.
Pattern is just the search pattern, type is what type of search to
perform, and casematters indicates whether the search is
case-sensitive. The types would work like this:
the bool works for me
Works for me, too. I'm too used to C and its use of "int" for everything.
Type 0 is a simple search. If the pattern occurs anywhere in the track
name, it's a match.
Type 1 is a wildcard search. The pattern must match the _entire_ track
name, * matches anything (including nothing), and ? matches one
character. \ makes the next character have its literal meaning.
Type 2 would be a regex search. Anything goes.
Use enums for better legibility, but yes this is fine.
Enums would be a good thing here, very true.
This could be done easily using the regex routines which are part of
libc. Additionally, regex.c (from the sed package) could be included to
link against for platforms that lack built-in regex support.
Does this address everyone's searching desires?
Also, after seeing the various searching suggestions that were posted
(especially the one about returning search results as a playlist), it
struck me that there are two fundamentally different types of searching
support.
Lets see how fundamentally differnt they are.
The first is a very flexible, powerful search that could look at
any (or all) of the metadata fields in the MusicCatalog and create a
playlist based on the results. This is great for graphical players, which
have a need for on-the-fly playlist modification and the ability to
import/export from the catalog.
Yes, that was my idea.
However, it is nearly useless for
text-based players which have a fixed playlist and no good way to
import/export from a db. The other method is a fast-and-dirty search that
would be quick and easy to use and only check a specific attribute of the
song. (eg., the pathname) This method would only return one result, but it
could be used multiple times to access different songs that matched the
pattern.
the API for that is larger than just FindSong. You need to start/stop
a given search.
I'm not so sure. I'll address this in a second.
This is very useful for the text-based players, which lack any
method of jumping to a given song in the playlist, but it is virtually
useless for graphical players, where the user can simply click on a song
to play it. I believe that most people want the first kind of searching
support, because most people like their GUIs. For backwards people like me
who still live in the stone age, the latter type is an absolute
necessity. Does this sound reasonable?
I have never used Freeamp on the console. Perhaps I should.
Yes you should, it's quite awesome.
A playlist seems to just a structure like (from PlaylistManager) :
vectorPlaylistItem* m_masterList
So what you actually want is an API like this
vectorPlaylistItem** PlaylistMananger::StartSearch(pattern,type,casematters)
Then make a function PlayFirst that takes the returned pointer, pops the first
PlaylistItem* off the vector, and jump to that song and starts playing it.
Then passing the returned pointer PlayFirst over and over will move forward
through the search results. This is the behavior you want.
Bind that to the a key, and you are set.
To let it loop from the last item to the first item again, move the
front item to the end of the vector instead of popping it off (might
want a deque instead of a vector).
Then make a StopSeach function that cleans up the vector when you are
done with the previous search and need a new one.
Since you call StopSearch right before StartSearch, you could even
combine them into the same function.
If you focus on the need to go through each search result in turn,
then having an internal view of the playlist like this (a sub-playlist)
makes sense.
Now all this assumes you want to start each new search at the top of
the playlist. If you want to start it form the currently (or most
recently played) song, then you could have a one function API:
"Go to first song after m_lastindex that matches the
pattern/type/casematters and play it"
Or you could mimic this by cylicing