grim/gplate

Added an iterator to GPlateObjectVariable
template_cleanup
2009-01-02, grim
6bf8035ff21e
Parents 01a3a67bdb80
Children ca6bb5eebe05
Added an iterator to GPlateObjectVariable
--- a/ChangeLog Thu Jan 01 01:04:23 2009 -0600
+++ b/ChangeLog Fri Jan 02 07:53:56 2009 -0600
@@ -1,3 +1,6 @@
+Version 0.0.3 ??/??/????:
+ * Added an iterator to GPlateObjectVariable
+
Version 0.0.2 09/20/2008:
* Fixed the bug where a default tag that didn't start with a word rendered
an empty string
--- a/gplate/variables/gplate-object-variable.c Thu Jan 01 01:04:23 2009 -0600
+++ b/gplate/variables/gplate-object-variable.c Fri Jan 02 07:53:56 2009 -0600
@@ -29,6 +29,11 @@
#define GPLATE_OBJECT_VARIABLE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE((obj), GPLATE_TYPE_OBJECT_VARIABLE, GPlateObjectVariablePrivate))
+#define GPLATE_TYPE_OBJECT_VARIABLE_ITERATOR (gplate_object_variable_iterator_get_gtype())
+#define GPLATE_OBJECT_VARIABLE_ITERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GPLATE_TYPE_OBJECT_VARIABLE_ITERATOR, GPlateObjectVariableIterator))
+
+static GType gplate_object_variable_iterator_get_gtype(void);
+
/******************************************************************************
* Enums
*****************************************************************************/
@@ -45,23 +50,215 @@
GObject *object;
} GPlateObjectVariablePrivate;
+typedef struct {
+ GObject gparent;
+
+ GPlateObjectVariable *objvar;
+
+ gboolean inited;
+
+ GParamSpec **elements;
+ guint current;
+ guint total;
+} GPlateObjectVariableIterator;
+
+typedef struct {
+ GObjectClass gparent;
+} GPlateObjectVariableIteratorClass;
+
/******************************************************************************
* Globals
*****************************************************************************/
static GObjectClass *parent_class = NULL;
+static GObjectClass *iterator_parent_class = NULL;
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static GPlateVariable *
+gplate_variable_from_paramspec(GObject *obj, GParamSpec *pspec) {
+ GPlateVariable *variable = NULL;
+ GValue value;
+ const gchar *name = g_param_spec_get_name(pspec);
+
+ g_object_get_property(obj, name, &value);
+
+ switch(G_PARAM_SPEC_VALUE_TYPE(pspec)) {
+ case G_TYPE_STRING:
+ variable =
+ gplate_variable_new_from_string(name,
+ g_value_get_string(&value));
+ break;
+ case G_TYPE_INT:
+ variable =
+ gplate_variable_new_from_integer(name,
+ g_value_get_int(&value));
+ break;
+ case G_TYPE_FLOAT:
+ variable =
+ gplate_variable_new_from_float(name,
+ g_value_get_float(&value));
+ break;
+ case G_TYPE_DOUBLE:
+ variable =
+ gplate_variable_new_from_double(name,
+ g_value_get_double(&value));
+ break;
+ case G_TYPE_OBJECT:
+ variable = gplate_object_variable_new_from_object(name,
+ g_value_get_object(&value));
+ break;
+ default:
+ variable = NULL;
+ break;
+ }
+
+ return variable;
+}
/******************************************************************************
- * Interface Stuff
+ * Iterator Interface Stuff
+ *****************************************************************************/
+static gboolean
+gplate_object_variable_iterator_has_next(const GPlateIterator *iter) {
+ GPlateObjectVariableIterator *realiter =
+ GPLATE_OBJECT_VARIABLE_ITERATOR(iter);
+
+ if(realiter->inited)
+ return (realiter->current < realiter->total - 1);
+ else
+ return (realiter->elements != NULL);
+
+ return FALSE;
+}
+
+static GPlateVariable *
+gplate_object_variable_iterator_next(GPlateIterator *iter) {
+ GPlateObjectVariableIterator *realiter = NULL;
+ GObject *obj = NULL;
+ GParamSpec *pspec = NULL;
+
+ realiter = GPLATE_OBJECT_VARIABLE_ITERATOR(iter);
+
+ if(!realiter->inited) {
+ realiter->current = 0;
+ realiter->inited = TRUE;
+ } else {
+ realiter->current++;
+ }
+
+ if(realiter->current >= realiter->total)
+ return NULL;
+
+ pspec = realiter->elements[realiter->current];
+
+ obj = gplate_object_variable_get_object(realiter->objvar);
+
+ return gplate_variable_from_paramspec(obj, pspec);
+}
+
+static void
+gplate_object_variable_iterator_iface_init(GPlateIteratorIface *iface) {
+ iface->has_next = gplate_object_variable_iterator_has_next;
+ iface->next = gplate_object_variable_iterator_next;
+}
+
+/******************************************************************************
+ * Iterator Object Stuff
+ *****************************************************************************/
+static void
+gplate_object_variable_iterator_finalize(GObject *obj) {
+ GPlateObjectVariableIterator *iter = GPLATE_OBJECT_VARIABLE_ITERATOR(obj);
+
+ g_object_unref(iter->objvar);
+ g_free(iter->elements);
+
+ G_OBJECT_CLASS(iterator_parent_class)->finalize(obj);
+}
+
+static void
+gplate_object_variable_iterator_class_init(
+ GPlateObjectVariableIteratorClass *klass)
+{
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ iterator_parent_class = g_type_class_peek_parent(klass);
+
+ obj_class->finalize = gplate_object_variable_iterator_finalize;
+}
+
+/******************************************************************************
+ * Iterator API
+ *****************************************************************************/
+static GType
+gplate_object_variable_iterator_get_gtype(void) {
+ static GType type = 0;
+
+ if(G_UNLIKELY(type == 0)) {
+ static const GTypeInfo info = {
+ sizeof(GPlateObjectVariableIteratorClass),
+ NULL,
+ NULL,
+ (GClassInitFunc)gplate_object_variable_iterator_class_init,
+ NULL,
+ NULL,
+ sizeof(GPlateObjectVariableIterator),
+ 0,
+ NULL,
+ };
+
+ static const GInterfaceInfo iterator_info = {
+ (GInterfaceInitFunc)gplate_object_variable_iterator_iface_init,
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static(G_TYPE_OBJECT,
+ "GPlateObjectVariableIterator",
+ &info, 0);
+
+ g_type_add_interface_static(type, GPLATE_TYPE_ITERATOR,
+ &iterator_info);
+ }
+
+ return type;
+}
+
+static GPlateIterator *
+gplate_object_variable_iterator_new(GPlateObjectVariable *objvar) {
+ GPlateIterator *iter = NULL;
+ GPlateObjectVariableIterator *realiter = NULL;
+ GPlateObjectVariablePrivate *priv = NULL;
+ GObjectClass *klass = NULL;
+
+ iter = g_object_new(GPLATE_TYPE_OBJECT_VARIABLE_ITERATOR, NULL);
+
+ realiter = GPLATE_OBJECT_VARIABLE_ITERATOR(iter);
+
+ realiter->objvar = g_object_ref(objvar);
+
+ priv = GPLATE_OBJECT_VARIABLE_GET_PRIVATE(objvar);
+
+ klass = G_OBJECT_GET_CLASS(priv->object);
+ realiter->elements = g_object_class_list_properties(klass,
+ &realiter->total);
+
+ realiter->current = 0;
+ realiter->inited = FALSE;
+
+ return iter;
+}
+
+/******************************************************************************
+ * Collection Interface Stuff
*****************************************************************************/
static GPlateVariable *
gplate_object_variable_find_variable(const GPlateCollection *collection,
const gchar *name)
{
GPlateObjectVariablePrivate *priv = NULL;
- GPlateVariable *variable = NULL;
GParamSpec *pspec = NULL;
GObjectClass *obj_class = NULL;
- GValue val = { 0, };
gchar *aname = NULL, *dot = NULL;
g_return_val_if_fail(name, NULL);
@@ -94,48 +291,24 @@
if(!G_IS_PARAM_SPEC(pspec))
return NULL;
- /* We know the type early, so we'll initialize our value to that type */
- g_value_init(&val, G_PARAM_SPEC_VALUE_TYPE(pspec));
+ /* now we have the value, so let's create our variable */
+ return gplate_variable_from_paramspec(priv->object, pspec);
+}
- /* now we have the value, so let's create our variable */
- switch(G_PARAM_SPEC_VALUE_TYPE(pspec)) {
- case G_TYPE_STRING:
- variable =
- gplate_variable_new_from_string(g_param_spec_get_name(pspec),
- g_value_get_string(&val));
- break;
- case G_TYPE_INT:
- variable =
- gplate_variable_new_from_integer(g_param_spec_get_name(pspec),
- g_value_get_int(&val));
- break;
- case G_TYPE_FLOAT:
- variable =
- gplate_variable_new_from_float(g_param_spec_get_name(pspec),
- g_value_get_float(&val));
- break;
- case G_TYPE_DOUBLE:
- variable =
- gplate_variable_new_from_double(g_param_spec_get_name(pspec),
- g_value_get_double(&val));
- break;
- case G_TYPE_OBJECT:
- variable = gplate_object_variable_new_from_object(
- g_param_spec_get_name(pspec),
- g_value_get_object(&val));
- break;
- default:
- variable = NULL;
- break;
- }
-
- return variable;
+static GPlateIterator *
+gplate_object_variable_get_iterator(GPlateCollection *collection) {
+ GPlateObjectVariable *objvar = GPLATE_OBJECT_VARIABLE(collection);
+
+ return gplate_object_variable_iterator_new(objvar);
}
static void
gplate_object_variable_collection_init(GPlateCollectionIface *iface) {
iface->find_variable = gplate_object_variable_find_variable;
iface->add_variable_with_name = NULL;
+ iface->remove_variable = NULL;
+ iface->remove_all = NULL;
+ iface->get_iterator = gplate_object_variable_get_iterator;
}
/******************************************************************************