From: Zeeshan Ali (Khattak) Date: Wed, 16 Sep 2009 17:23:18 +0000 (+0300) Subject: core: A simple MediaContainer implementation X-Git-Tag: RYGEL_0_4~69 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0817c4dbe9f19ae5f8a986d6540e26b93f9d4729;p=profile%2Fivi%2Frygel.git core: A simple MediaContainer implementation --- diff --git a/src/rygel/Makefile.am b/src/rygel/Makefile.am index 47834ba..e2e7e5f 100644 --- a/src/rygel/Makefile.am +++ b/src/rygel/Makefile.am @@ -64,6 +64,7 @@ VAPI_SOURCE_FILES = rygel-configuration.vala \ rygel-plugin-loader.vala \ rygel-media-object.vala \ rygel-media-container.vala \ + rygel-simple-container.vala \ rygel-simple-async-result.vala \ rygel-media-item.vala \ rygel-thumbnail.vala \ diff --git a/src/rygel/rygel-simple-container.vala b/src/rygel/rygel-simple-container.vala new file mode 100644 index 0000000..40901d7 --- /dev/null +++ b/src/rygel/rygel-simple-container.vala @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2009 Zeeshan Ali (Khattak) . + * Copyright (C) 2009 Nokia Corporation. + * + * Author: Zeeshan Ali (Khattak) + * + * + * This file is part of Rygel. + * + * Rygel is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Rygel is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +using Gee; + +/** + * A simple implementation of MediaContainer that keeps all MediaObjects + * in memory. In order for it to be of any use, you must add children to + * children ArrayList field. + */ +public class Rygel.SimpleContainer : Rygel.MediaContainer { + public ArrayList children; + + private ArrayList searches; + + public SimpleContainer (string id, + MediaContainer? parent, + string title) { + base (id, parent, title, 0); + + this.children = new ArrayList (); + this.searches = new ArrayList (); + } + + public override void get_children (uint offset, + uint max_count, + Cancellable? cancellable, + AsyncReadyCallback callback) { + uint stop = offset + max_count; + stop = stop.clamp (0, this.child_count); + + var media_objects = this.children.slice ((int) offset, (int) stop); + + var res = new Rygel.SimpleAsyncResult> + (this, callback); + res.data = media_objects; + res.complete_in_idle (); + } + + public override Gee.List? get_children_finish ( + AsyncResult res) + throws GLib.Error { + var simple_res = (Rygel.SimpleAsyncResult>) res; + return simple_res.data; + } + + public override void find_object (string id, + Cancellable? cancellable, + AsyncReadyCallback callback) { + var res = new Rygel.SimpleAsyncResult (this, callback); + + MediaObject child = null; + + foreach (var tmp in this.children) { + if (id == tmp.id) { + child = tmp; + + break; + } + } + + if (child != null) { + res.data = child; + res.complete_in_idle (); + } else { + var containers = new ArrayList (); + + foreach (var tmp in this.children) { + if (tmp is MediaContainer) { + containers.add (tmp as MediaContainer); + } + } + + var search = new ObjectSearch (id, containers, res); + search.completed.connect (this.on_object_search_completed); + + this.searches.add (search); + + search.run (cancellable); + } + } + + public override MediaObject? find_object_finish (AsyncResult res) + throws GLib.Error { + var simple_res = (Rygel.SimpleAsyncResult) res; + + if (simple_res.error != null) { + throw simple_res.error; + } else { + return simple_res.data; + } + } + + private void on_object_search_completed (StateMachine state_machine) { + var search = state_machine as ObjectSearch; + + search.res.complete (); + + this.searches.remove (search); + } +} + +private class Rygel.ObjectSearch : GLib.Object, Rygel.StateMachine { + public string id; + public ArrayList containers; + public Rygel.SimpleAsyncResult res; + + public ObjectSearch (string id, + ArrayList containers, + SimpleAsyncResult res) { + this.id = id; + this.containers = containers; + this.res = res; + } + + public void run (Cancellable? cancellable) { + var container = this.containers.get (0); + + if (container != null) { + container.find_object (this.id, + cancellable, + this.on_object_found); + } else { + this.completed (); + } + } + + private void on_object_found (Object source_object, + AsyncResult res) { + try { + var container = source_object as MediaContainer; + this.res.data = container.find_object_finish (res); + + if (this.res.data == null) { + // continue the search + this.containers.remove_at (0); + + // FIXME: We are loosing the 'cancellable' from the first call + this.run (null); + } else { + this.completed (); + } + } catch (Error err) { + warning ("Error while searching for '%s': %s\n", + this.id, + err.message); + this.completed (); + } + } +}