[rygel] core: A simple MediaContainer implementation



commit 0817c4dbe9f19ae5f8a986d6540e26b93f9d4729
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Wed Sep 16 20:23:18 2009 +0300

    core: A simple MediaContainer implementation

 src/rygel/Makefile.am                 |    1 +
 src/rygel/rygel-simple-container.vala |  171 +++++++++++++++++++++++++++++++++
 2 files changed, 172 insertions(+), 0 deletions(-)
---
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) <zeeshanak gnome org>.
+ * Copyright (C) 2009 Nokia Corporation.
+ *
+ * Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
+ *                               <zeeshan ali nokia com>
+ *
+ * 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<MediaObject> children;
+
+    private ArrayList<ObjectSearch> searches;
+
+    public SimpleContainer (string          id,
+                            MediaContainer? parent,
+                            string          title) {
+        base (id, parent, title, 0);
+
+        this.children = new ArrayList<MediaObject> ();
+        this.searches = new ArrayList<ObjectSearch> ();
+    }
+
+    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<Gee.List<MediaObject>>
+                                                (this, callback);
+        res.data = media_objects;
+        res.complete_in_idle ();
+    }
+
+    public override Gee.List<MediaObject>? get_children_finish (
+                                                         AsyncResult res)
+                                                         throws GLib.Error {
+        var simple_res = (Rygel.SimpleAsyncResult<Gee.List<MediaObject>>) res;
+        return simple_res.data;
+    }
+
+    public override void find_object (string             id,
+                                      Cancellable?       cancellable,
+                                      AsyncReadyCallback callback) {
+        var res = new Rygel.SimpleAsyncResult<MediaObject> (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<MediaContainer> ();
+
+            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<MediaObject>) 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<MediaContainer> containers;
+    public Rygel.SimpleAsyncResult<MediaObject> res;
+
+    public ObjectSearch (string                         id,
+                         ArrayList<MediaContainer>      containers,
+                         SimpleAsyncResult<MediaObject> 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 ();
+        }
+    }
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]