2009-12-03 Jeffrey Stedfast <fejj@novell.com>
[moon.git] / src / applier.cpp
blob909c16997a06e9dfea9934fb2c6bf123a00d2a74
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Contact:
4 * Moonlight List (moonlight-list@lists.ximian.com)
6 * Copyright 2007 Novell, Inc. (http://www.novell.com)
8 * See the LICENSE file included with the distribution for details.
9 *
12 #include "applier.h"
14 typedef struct {
15 DependencyObject *object;
16 GList *properties_list;
17 } object_indexer;
19 typedef struct {
20 DependencyProperty *property;
21 GList *values_list;
22 } property_indexer;
24 typedef struct {
25 int precedence;
26 Value *v;
27 } value_indexer;
29 Applier::Applier ()
31 readonly = false;
32 objects = NULL;
35 Applier::~Applier ()
37 if (objects) {
38 readonly = true;
39 Flush ();
43 static gint
44 property_indexer_compare_func (property_indexer *a, property_indexer *b)
46 if (a->property == b->property)
47 return 0;
48 else
49 return -1;
52 static gint
53 value_indexer_compare_func (value_indexer *a, value_indexer *b)
55 if (a->precedence < b->precedence)
56 return -1;
57 else if (a->precedence > b->precedence)
58 return 1;
59 else
60 return 0;
63 void
64 Applier::AddPropertyChange (DependencyObject *object, DependencyProperty *property, Value *v, int precedence)
66 if (readonly) {
67 g_warning ("Applier::AddPropertyChange is being called during shutdown");
68 delete v;
69 return;
72 if (precedence == APPLIER_PRECEDENCE_INSTANT) {
73 object->SetValue (property, *v);
74 delete v;
75 return;
78 value_indexer *v_indexer = NULL;
79 property_indexer *p_indexer = NULL;
80 object_indexer *o_indexer = NULL;
82 if (!objects)
83 objects = g_hash_table_new (g_direct_hash, g_direct_equal);
84 else
85 o_indexer = (object_indexer *) g_hash_table_lookup (objects, object);
87 if (o_indexer == NULL) {
88 o_indexer = g_new (object_indexer, 1);
89 o_indexer->object = object;
90 object->ref ();
91 o_indexer->properties_list = NULL;
92 g_hash_table_insert (objects, object, o_indexer);
95 GList *list_item = g_list_find_custom (o_indexer->properties_list, property, (GCompareFunc) property_indexer_compare_func);
97 if (list_item != NULL)
98 p_indexer = (property_indexer *) list_item->data;
100 if (p_indexer == NULL) {
101 p_indexer = g_new (property_indexer, 1);
102 p_indexer->property = property;
103 p_indexer->values_list = NULL;
104 o_indexer->properties_list = g_list_append (o_indexer->properties_list, p_indexer);
107 v_indexer = g_new (value_indexer, 1);
108 v_indexer->precedence = precedence;
109 v_indexer->v = v;
111 p_indexer->values_list = g_list_insert_sorted (p_indexer->values_list, v_indexer, (GCompareFunc) value_indexer_compare_func);
114 static void
115 destroy_value_func (value_indexer *v_indexer, gpointer unused)
117 g_return_if_fail (v_indexer != NULL);
118 g_return_if_fail (v_indexer->v != NULL);
120 delete v_indexer->v;
121 v_indexer->v = NULL;
122 g_free (v_indexer);
125 static void
126 destroy_property_func (property_indexer *p_indexer, gpointer unused)
128 g_return_if_fail (p_indexer != NULL);
129 g_return_if_fail (p_indexer->values_list != NULL);
131 g_list_foreach (p_indexer->values_list, (GFunc) destroy_value_func, NULL);
132 g_list_free (p_indexer->values_list);
133 p_indexer->property = NULL;
134 p_indexer->values_list = NULL;
135 g_free (p_indexer);
138 static void
139 destroy_object_func (DependencyObject *object, object_indexer *o_indexer, gpointer unused)
141 g_return_if_fail (object != NULL);
142 g_return_if_fail (o_indexer != NULL);
144 g_list_foreach (o_indexer->properties_list, (GFunc) destroy_property_func, NULL);
145 g_list_free (o_indexer->properties_list);
146 object->unref ();
147 g_free (o_indexer);
150 static void
151 apply_property_func (property_indexer *p_indexer, DependencyObject *object)
153 g_return_if_fail (p_indexer->property != NULL);
154 g_return_if_fail (p_indexer->values_list != NULL);
156 value_indexer *v_indexer = (value_indexer *) p_indexer->values_list->data;
157 object->SetValue (p_indexer->property, *v_indexer->v);
160 static void
161 apply_object_func (DependencyObject *object, object_indexer *o_indexer, gpointer unused)
163 g_return_if_fail (o_indexer != NULL);
165 g_list_foreach (o_indexer->properties_list, (GFunc) apply_property_func, object);
168 void
169 Applier::Apply ()
171 if (objects)
172 g_hash_table_foreach (objects, (GHFunc) apply_object_func, NULL);
175 void
176 Applier::Flush ()
178 if (objects) {
179 g_hash_table_foreach (objects, (GHFunc) destroy_object_func, NULL);
180 g_hash_table_destroy (objects);
181 objects = NULL;