[gxml] GomCollection: Implements Gee's Traversable, Iterable
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gxml] GomCollection: Implements Gee's Traversable, Iterable
- Date: Wed, 7 Feb 2018 19:52:55 +0000 (UTC)
commit 054828f3c1e2329b8e8be14ae67aa0a614363702
Author: Daniel Espinosa <esodan gmail com>
Date: Wed Feb 7 12:16:49 2018 -0600
GomCollection: Implements Gee's Traversable, Iterable
gxml/GomCollections.vala | 69 +++++++++++++++++++++++++++++----------
test/GomSerializationTest.vala | 25 ++++++++++++++
2 files changed, 76 insertions(+), 18 deletions(-)
---
diff --git a/gxml/GomCollections.vala b/gxml/GomCollections.vala
index a91582d..07cf535 100644
--- a/gxml/GomCollections.vala
+++ b/gxml/GomCollections.vala
@@ -25,17 +25,15 @@ using Gee;
* A DOM4 interface to keep references to {@link DomElement} in a {@link element}
* child nodes. Only {@link GomObject} are supported.
*/
-public interface GXml.GomCollection : Object
+public interface GXml.GomCollection : Object, Traversable, Iterable
{
/**
* A list of child {@link DomElement} objects of {@link element}
*/
- [CCode (ordering = 0)]
public abstract GLib.Queue<int> nodes_index { get; }
/**
* A {@link GomElement} with all child elements in collection.
*/
- [CCode (ordering = 1)]
public abstract GomElement element { get; construct set; }
/**
* Local name of {@link DomElement} objects of {@link element}, which could be
@@ -43,7 +41,6 @@ public interface GXml.GomCollection : Object
*
* Used when reading to add elements to collection.
*/
- [CCode (ordering = 2)]
public abstract string items_name { get; }
/**
* A {@link GLib.Type} of {@link DomElement} child objects of {@link element},
@@ -51,19 +48,16 @@ public interface GXml.GomCollection : Object
*
* Type should be an {@link GomObject}.
*/
- [CCode (ordering = 3)]
public abstract Type items_type { get; construct set; }
/**
* Search and add references to all {@link GomObject} nodes as child of
* {@link element} with same, case insensitive, name of {@link items_name}
*/
- [CCode (ordering = 4)]
public abstract void search () throws GLib.Error;
/**
* Gets a child {@link DomElement} of {@link element} referenced in
* {@link nodes_index}.
*/
- [CCode (ordering = 5)]
public virtual DomElement? get_item (int index) throws GLib.Error {
if (nodes_index.length == 0)
return null;
@@ -86,12 +80,10 @@ public interface GXml.GomCollection : Object
* collection, this method will take information from node to initialize
* how to find it.
*/
- [CCode (ordering = 6)]
public abstract void append (DomElement node) throws GLib.Error;
/**
* Number of items referenced in {@link nodes_index}
*/
- [CCode (ordering = 7)]
public virtual int length { get { return (int) nodes_index.get_length (); } }
/**
* Initialize collection to use a given {@link GomElement} derived type.
@@ -101,7 +93,6 @@ public interface GXml.GomCollection : Object
* This method can be used at construction time of classes implementing
* {@link GomCollection} to initialize object type to refer in collection.
*/
- [CCode (ordering = 8)]
public abstract void initialize (GLib.Type t) throws GLib.Error;
/**
* Creates a new instance of {@link items_type}, with same
@@ -111,7 +102,6 @@ public interface GXml.GomCollection : Object
*
* Returns: a new instance object or null if type is not a {@link GomElement} or no parent has been set
*/
- [CCode (ordering = 9)]
public virtual GomElement? create_item () {
if (items_type.is_a (GLib.Type.INVALID)) return null;
if (!items_type.is_a (typeof (GomElement))) return null;
@@ -128,12 +118,10 @@ public interface GXml.GomCollection : Object
*
* Return: true if node and index should be added to collection.
*/
- [CCode (ordering = 10)]
public abstract bool validate_append (int index, DomElement element) throws GLib.Error;
/**
* Clear this collection in prepareation for a search
*/
- [CCode (ordering = 11)]
public abstract void clear () throws GLib.Error;
}
@@ -145,7 +133,7 @@ public interface GXml.GomCollection : Object
* in order to be able to add new references to elements. Use {@link initialize_element}
* to set parent element and {@link search} to find elements for collection.
*/
-public abstract class GXml.BaseCollection : Object {
+public abstract class GXml.BaseCollection : Object, Traversable<DomElement>, Iterable<DomElement>,
GomCollection {
/**
* A collection of node's index refered. Don't modify it manually.
*/
@@ -278,6 +266,51 @@ public abstract class GXml.BaseCollection : Object {
* {@inheritDoc}
*/
public virtual void clear () throws GLib.Error {}
+
+ // Traversable Interface
+ public bool @foreach (ForallFunc<DomElement> f) {
+ var i = iterator ();
+ return i.foreach (f);
+ }
+ // Itarable Interface
+ public Iterator<DomElement> iterator () { return new GomCollectionIterator (this); }
+ // For Iterable interface implementation
+ private class GomCollectionIterator : Object, Traversable<DomElement>, Iterator<DomElement> {
+ private int pos;
+ private GomCollection _collection;
+ public bool read_only { get { return false; } }
+ public bool valid { get { return (pos >= 0 && pos < _collection.length); } }
+
+ public GomCollectionIterator (GomCollection col) {
+ _collection = col;
+ pos = -1;
+ }
+
+ public DomElement @get ()
+ requires (pos >= 0 && pos < _collection.length) {
+ return _collection.get_item (pos);
+ }
+ public bool has_next () { return (pos + 1 < _collection.length); }
+ public bool next () {
+ if (!has_next ()) return false;
+ pos++;
+ return true;
+ }
+ public void remove () {
+ var n = _collection.get_item (pos);
+ if (n == null) return;
+ n.remove ();
+ _collection.search ();
+ }
+
+ public bool @foreach (ForallFunc<DomElement> f) {
+ while (has_next ()) {
+ next ();
+ if (!f (get ())) return false;
+ }
+ return true;
+ }
+ }
}
/**
@@ -300,7 +333,7 @@ public abstract class GXml.BaseCollection : Object {
* }
* }}}
*/
-public class GXml.GomArrayList : GXml.BaseCollection, GomCollection {
+public class GXml.GomArrayList : GXml.BaseCollection {
public override bool validate_append (int index, DomElement element) throws GLib.Error {
#if DEBUG
GLib.message ("Adding node:"+element.node_name);
@@ -348,7 +381,7 @@ public interface GXml.MappeableElement : Object, DomElement {
* }
* }}}
*/
-public class GXml.GomHashMap : GXml.BaseCollection, GXml.GomCollection {
+public class GXml.GomHashMap : GXml.BaseCollection {
/**
* A hashtable with all keys as string to node's index refered. Don't modify it manually.
*/
@@ -505,7 +538,7 @@ public interface GXml.MappeableElementPairKey : Object, DomElement {
* }
* }}}
*/
-public class GXml.GomHashPairedMap : GXml.BaseCollection, GXml.GomCollection {
+public class GXml.GomHashPairedMap : GXml.BaseCollection {
/**
* A hashtable with all keys as string to node's index refered. Don't modify it manually.
*/
@@ -731,7 +764,7 @@ public interface GXml.MappeableElementThreeKey : Object, DomElement {
* }
* }}}
*/
-public class GXml.GomHashThreeMap : GXml.BaseCollection, GXml.GomCollection {
+public class GXml.GomHashThreeMap : GXml.BaseCollection {
/**
* A hashtable with all keys as string to node's index refered. Don't modify it manually.
*/
diff --git a/test/GomSerializationTest.vala b/test/GomSerializationTest.vala
index debbc69..22a9d9b 100644
--- a/test/GomSerializationTest.vala
+++ b/test/GomSerializationTest.vala
@@ -1355,5 +1355,30 @@ class GomSerializationTest : GXmlTest {
assert_not_reached ();
}
});
+ Test.add_func ("/gxml/gom-serialization/collection/iteration", () => {
+ try {
+ var bs = new BookStore ();
+ assert (bs.books == null);
+ bs.set_instance_property ("books");
+ int n = 1;
+ for (int i = 0; i < 10; i++) {
+ var b = bs.books.create_item () as Book;
+ assert (b != null);
+ b.name = "Title %d".printf (n);
+ n++;
+ bs.books.append (b);
+ }
+ message (bs.write_string ());
+ n = 1;
+ foreach (DomElement e in bs.books) {
+ assert ((e as Book) != null);
+ assert ((e as Book).name == "Title %d".printf (n));
+ n++;
+ }
+ } catch (GLib.Error e) {
+ GLib.message ("Error: "+e.message);
+ assert_not_reached ();
+ }
+ });
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]