*
* Various GStreamer objects provide access to their internal structures using
* an iterator.
+ *
+ * The basic use pattern of an iterator is as follows:
+ *
+ * <example>
+ * <title>Using an iterator</title>
+ * <programlisting>
+ * it = _get_iterator(object);
+ * done = FALSE;
+ * while (!done) {
+ * switch (gst_iterator_next (it, &item)) {
+ * case GST_ITERATOR_OK:
+ * ... use/change item here...
+ * gst_object_unref (item);
+ * break;
+ * case GST_ITERATOR_RESYNC:
+ * ...rollback changes to items...
+ * gst_iterator_resync (it);
+ * break;
+ * case GST_ITERATOR_DONE:
+ * done = TRUE;
+ * break;
+ * }
+ * }
+ * gst_iterator_free (it);
+ * </programlisting>
+ * </example>
*/
#include "gst_private.h"
result = gst_iterator_next (iter, &item);
switch (result) {
case GST_ITERATOR_OK:
- /* fixme: is there a way to ref/unref items? */
+ /* FIXME: is there a way to ref/unref items? */
if (!func (item, ret, user_data))
goto fold_done;
else
*
* The iterator will not be freed.
*
+ * This function will return NULL if an error or resync happened to
+ * the iterator.
+ *
* Returns: The element in the iterator that matches the compare
* function or NULL when no element matched.
*
data.func = func;
data.user_data = user_data;
+ /* FIXME, we totally ignore RESYNC and return NULL so that the
+ * app does not know if the element was not found or a resync happened */
res =
gst_iterator_fold (iter, (GstIteratorFoldFunction) find_custom_fold_func,
&ret, &data);
G_BEGIN_DECLS
+/**
+ * GstIteratorResult:
+ * @GST_ITERATOR_DONE: No more items in the iterator
+ * @GST_ITERATOR_OK: An item was retrieved
+ * @GST_ITERATOR_RESYNC: Datastructure changed while iterating
+ * @GST_ITERATOR_ERROR: An error happened
+ *
+ * The result of gst_iterator_next().
+ */
typedef enum {
- GST_ITERATOR_DONE = 0, /* no more items in the iterator */
- GST_ITERATOR_OK = 1, /* item retrieved */
- GST_ITERATOR_RESYNC = 2, /* datastructures changed while iterating */
- GST_ITERATOR_ERROR = 3, /* some error happened */
+ GST_ITERATOR_DONE = 0,
+ GST_ITERATOR_OK = 1,
+ GST_ITERATOR_RESYNC = 2,
+ GST_ITERATOR_ERROR = 3,
} GstIteratorResult;
typedef struct _GstIterator GstIterator;
+/**
+ * GstIteratorItem:
+ * @GST_ITERATOR_ITEM_SKIP: Skip this item
+ * @GST_ITERATOR_ITEM_PASS: Return item
+ * @GST_ITERATOR_ITEM_END: Stop after this item.
+ *
+ * The result of a GstIteratorItemFunction.
+ */
typedef enum {
- GST_ITERATOR_ITEM_SKIP = 0, /* skip item */
- GST_ITERATOR_ITEM_PASS = 1, /* return item */
- GST_ITERATOR_ITEM_END = 2, /* stop after this item */
+ GST_ITERATOR_ITEM_SKIP = 0,
+ GST_ITERATOR_ITEM_PASS = 1,
+ GST_ITERATOR_ITEM_END = 2,
} GstIteratorItem;
+/**
+ * GstIteratorDisposeFunction:
+ * @owner: the owner of the iterator
+ *
+ * The function that will be called when a GList iterator is freed. The
+ * owner of the GList iterator can then clean up its resources.
+ */
typedef void (*GstIteratorDisposeFunction) (gpointer owner);
+/**
+ * GstIteratorNextFunction:
+ * @it: the iterator
+ * @result: a pointer to hold the next item
+ *
+ * The function that will be called when the next element of the iterator
+ * should be retrieved.
+ *
+ * Implementors of a #GstIterator should implement this
+ * function and pass it to the constructor of the custom iterator.
+ * The function will be called with the iterator lock held.
+ *
+ * Returns: the result of the operation.
+ */
typedef GstIteratorResult (*GstIteratorNextFunction) (GstIterator *it, gpointer *result);
+/**
+ * GstIteratorItemFunction:
+ * @it: the iterator
+ * @item: the item being retrieved.
+ *
+ * The function that will be called after the next item of the iterator
+ * has been retrieved. This function will typically increase the refcount
+ * of the item or make a copy.
+ *
+ * Implementors of a #GstIterator should implement this
+ * function and pass it to the constructor of the custom iterator.
+ * The function will be called with the iterator lock held.
+ *
+ * Returns: the result of the operation.
+ */
typedef GstIteratorItem (*GstIteratorItemFunction) (GstIterator *it, gpointer item);
+/**
+ * GstIteratorResyncFunction:
+ * @it: the iterator
+ *
+ * This function will be called whenever a concurrent update happened
+ * to the iterated datastructure. The implementor of the iterator should
+ * restart the iterator from the beginning and clean up any state it might
+ * have.
+ *
+ * Implementors of a #GstIterator should implement this
+ * function and pass it to the constructor of the custom iterator.
+ * The function will be called with the iterator lock held.
+ */
typedef void (*GstIteratorResyncFunction) (GstIterator *it);
+/**
+ * GstIteratorFreeFunction:
+ * @it: the iterator
+ *
+ * This function will be called when the iterator is freed.
+ *
+ * Implementors of a #GstIterator should implement this
+ * function and pass it to the constructor of the custom iterator.
+ * The function will be called with the iterator lock held.
+ */
typedef void (*GstIteratorFreeFunction) (GstIterator *it);
+/**
+ * GstIteratorFoldFunction:
+ * @item: the item to fold
+ * @ret: a GValue collecting the result
+ * @user_data: data passed to #gst_iterator_fold
+ *
+ * A function to be passed to #gst_iterator_fold.
+ *
+ * Returns: TRUE if the fold should continue, FALSE if it should stop.
+ */
typedef gboolean (*GstIteratorFoldFunction) (gpointer item, GValue *ret, gpointer user_data);
+/**
+ * GST_ITERATOR:
+ * @it: the #GstIterator value
+ *
+ * Macro to cast to a #GstIterator
+ */
#define GST_ITERATOR(it) ((GstIterator*)(it))
+/**
+ * GST_ITERATOR_LOCK:
+ * @it: the #GstIterator to get the lock of
+ *
+ * Macro to get the lock protecting the datastructure being iterated.
+ */
#define GST_ITERATOR_LOCK(it) (GST_ITERATOR(it)->lock)
+/**
+ * GST_ITERATOR_COOKIE:
+ * @it: the #GstIterator to get the cookie of
+ *
+ * Macro to get the cookie of a #GstIterator. The cookie of the
+ * iterator is the value of the master cookie when the iterator
+ * was created.
+ * Whenever the iterator is iterated, the value is compared to the
+ * value of the master cookie. If they are different, a concurrent
+ * modification happened to the iterator and a resync is needed.
+ */
#define GST_ITERATOR_COOKIE(it) (GST_ITERATOR(it)->cookie)
+/**
+ * GST_ITERATOR_ORIG_COOKIE:
+ * @it: the #GstIterator to get the master cookie of
+ *
+ * Macro to get a pointer to where the master cookie is stored. The
+ * master cookie protects the structure being iterated and gets updated
+ * whenever the datastructure changes.
+ */
#define GST_ITERATOR_ORIG_COOKIE(it) (GST_ITERATOR(it)->master_cookie)
+/**
+ * GstIterator:
+ * @next: The function to get the next item in the iterator
+ * @item: The function to be called for each item retrieved
+ * @resync: The function to call when a resync is needed.
+ * @free: The function to call when the iterator is freed
+ * @pushed: The iterator that is currently pushed with gst_iterator_push()
+ * @type: The type of the object that this iterator will return
+ * @lock: The lock protecting the data structure and the cookie.
+ * @cookie: The cookie; the value of the master_cookie when this iterator was
+ * created.
+ * @master_cookie: A pointer to the master cookie.
+ *
+ * GstIterator base structure. The values of this structure are
+ * protected for subclasses, use the methods to use the #GstIterator.
+ */
struct _GstIterator {
+ /*< protected >*/
GstIteratorNextFunction next;
GstIteratorItemFunction item;
GstIteratorResyncFunction resync;