Meta API and collection architecture
Maximilian Kossick
mkossick at htwg-konstanz.de
Thu May 3 22:03:24 CEST 2007
Hi all,
today Nikolaj asked me about the Meta API and the collection architecture,
because he got the impression that he might be duplicating stuff for the
service framework that already exists as part of the new collection
architecture. Alexandre is familiar with it to some extent because he wrote
the new collection browser, and Martin, Bart, Sven and I talked about the
general architecture at FOSDEM, but I'm not sure how much the rest of you
actually know about it. The umbrello diagramm in amarok/docs describes an
architecture that is pretty close to the actual implementation, and might
therefore be helpful.
Meta API
The Meta API in meta.h is a replacement for MetaBundle. As far as I know, it
was already agreed at the k3m meeting last year that MetaBundle would have to
be refactored for Amarok 2.
The main goal of the Meta API is to increase maintainability by being more
object-oriented than MetaBundle in Amarok 1.x. It uses multiple classes to
represent tracks, artists, albums, composers, genres or years. Additionally,
the classes defined in meta.h are abstract and have to be implemented for
each collection.
A lot of the tasks which are handled by CollectionDB at the moment are going
to be moved to the classes of the Meta API. For example, instead of calling a
method of CollectionDB to get the album image of a song, you can now call a
method of Meta::Album (that particular method doesn't work yet because i
don't know what the return type is supposed to be, a QImage or the
EmbeddedImage thingy which is used currently, but I hope you get the idea)
Note: the Meta API isn't finished yet. I've been working on it and trying to
improve it for a while now, but i'm sure that it will have changed because
there are new requirements or the requirements are different from what i
expected. The best way to improve it is to use the API in the code, and
discuss possible changes on the ML or on IRC. There are two implementations
in SVN at the moment, and i have at least one more (an implementaion which
handles streams) on my harddisk, so changes to the API force us to change
quite a few other files and should therefore be carefully thought through.
Collection architecture and QueryMaker
The idea behind the new collection architecture is that there are different
types of collections ( for example music on an ipod, the files on your
computer backed by a relational database, or a DAAP server), and Amarok
should be able to handle all of them the same way. In particular should it be
possible for smart or dynamic playlists to load songs on a daap server or on
an ipod into the playlist ( that would allow Amarok to load the music on
pwsp.net into the playlist automatically, or allow it to play the music on a
friend's ipod at a party ).
To achieve the goal decribed above I created QueryMaker, which is the
replacement of QueryBuilder. Unlike QueryBuilder, QueryMaker does not have
any SQL-isms in its API. QueryMaker's API is still work in progress. The
parts of the API which are needed for smart playlists or the filtering in the
collection browser are not implemented yet.
I've created a few support classes which should make it easier to implement a
new collection. The classes are located in collection/support and are called
MemoryCollection and MemoryQueryMaker. Check the DAAP collection
implementation to see how they are used. They are probably not very fast, and
the whole collection has to be loaded into memory, but they should make it
easier to implement a new collection.
How to use all this stuff
CollectionManager::trackForUrl( KUrl ) is a factory method which creates Track
object for the given url (or it will do that as soon as it's more than the
stub that it is now). So whenever you have an url and want a track object for
it you can use that method, which will try to figure the correct Track
implementation for the url.
You can get a list of all available collections by calling
CollectionManager::collections(). You can query a specific collection by
getting a QueryMaker object directly from the collection, or you can query
all collections in parallel by using the QueryMaker object returned by
CollectionManager::queryBuilder().
To use QueryMaker, you first have to select the type of query you want to
execute by calling one of the start*Query() methods. Depending on the method
you called, a different signal is emitted with the result of the query. (
newResultReady( QString, Meta::DataList ) is a special case and probably only
necessary for the collection browser) After that, you can build the query by
calling methods on the QueryMaker instance. The API isn't finished yet, but
most of the available methods should be familiar to you from QueryBuilder.
Calling run() on the QueryMaker instance start the query, but also returns
immediately. The query is processed asynchronously and the results are
delivered by the QueryMaker object by emitting one of its signals. Please
note that it's possible that the signal is emitted multiple times, with
different results and a different collectionID each time. It is only safe to
delete the QueryMaker object after queryDone() was emitted.
BlockingQuery allows you to avoid the asynchronous nature of QueryMaker.
Configure the QueryMaker object, pass it to BlockingQuery's constructor, and
call startQuery(), which will block until the query is done.
Creating a new collection
To create a new collection, you'll have to implement the following classes:
CollectionFactory, Collection, QueryMaker, and all of the Meta classes.
If you use MemoryCollection and MemoryQueryMaker you won't have to implement
QueryMaker. Implementing the classes mentioned above and creating a plugin
makes it possible to show your collection in the collection browser. However
this is optional, your CollectionFactory implementation is free not to emit
the CollectionFactory::newCollection signal. Nikolay, this would allow you to
make it possible for the user to decide if the stores are shown in the
collection browser, if you want.
That's all which occurred to me right now, I'm sure I could write more about
it. I might do that tomorrow/on the weekend, or just ask me:)
Cheers, Max
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://mail.kde.org/pipermail/amarok-devel/attachments/20070503/52bc9dde/attachment.pgp
More information about the Amarok-devel
mailing list