4 * Copyright 2007 Novell, Inc. (http://www.novell.com)
6 * See the LICENSE file included with the distribution for details.
14 #include "namescope.h"
16 NameScope::NameScope ()
18 SetObjectType (Type::NAMESCOPE
);
25 NameScope::remove_handler (gpointer key
, gpointer value
, gpointer data
)
27 DependencyObject
*depobj
= (DependencyObject
*)value
;
28 depobj
->RemoveHandler (EventObject::DestroyedEvent
, NameScope::ObjectDestroyedEvent
, data
);
32 NameScope::~NameScope ()
35 g_hash_table_foreach_remove (names
, remove_handler
, this);
36 g_hash_table_destroy (names
);
41 register_name (char *key
, DependencyObject
*obj
, NameScope
* ns
)
43 ns
->RegisterName (key
, obj
);
47 NameScope::CloneCore (Types
*types
, DependencyObject
*fromObj
)
49 NameScope
*ns
= (NameScope
*)fromObj
;
51 g_hash_table_foreach (ns
->names
, (GHFunc
)register_name
, this);
53 is_locked
= ns
->is_locked
;
54 temporary
= ns
->temporary
;
61 g_hash_table_foreach_remove (names
, remove_handler
, this);
63 DependencyObject::Dispose ();
67 remove_object_from_namescope (gpointer key
, gpointer value
, gpointer user_data
)
69 return value
== user_data
;
73 NameScope::ObjectDestroyedEvent (EventObject
*sender
, EventArgs
*args
, gpointer closure
)
75 NameScope
*ns
= (NameScope
*)closure
;
76 // XXX this method worries me.. using GetName like this.
77 DependencyObject
*depobj
= (DependencyObject
*)sender
;
78 const char *name
= depobj
->GetName ();
80 g_hash_table_remove (ns
->names
, name
);
82 g_hash_table_foreach_remove (ns
->names
, remove_object_from_namescope
, depobj
);
87 NameScope::RegisterName (const char *name
, DependencyObject
*object
)
93 names
= g_hash_table_new_full (g_str_hash
, g_str_equal
,
94 (GDestroyNotify
)g_free
,
98 DependencyObject
*existing_object
= (DependencyObject
*)g_hash_table_lookup (names
, name
);
99 if (existing_object
== object
)
102 if (existing_object
) {
103 existing_object
->RemoveHandler (EventObject::DestroyedEvent
, ObjectDestroyedEvent
, this);
106 object
->AddHandler (EventObject::DestroyedEvent
, NameScope::ObjectDestroyedEvent
, this);
107 g_hash_table_insert (names
, g_strdup (name
), object
);
111 NameScope::UnregisterName (const char *name
)
119 DependencyObject
*depobj
= (DependencyObject
*)g_hash_table_lookup (names
, name
);
121 depobj
->RemoveHandler (EventObject::DestroyedEvent
, ObjectDestroyedEvent
, this);
123 g_hash_table_remove (names
, name
);
128 NameScope::FindName (const char *name
)
134 g_warning ("NameScope::FindName (null)");
137 return (DependencyObject
*) g_hash_table_lookup (names
, name
);
141 NameScope::merge_name (gpointer key
, gpointer value
, gpointer user_data
)
143 char *name
= (char*)key
;
144 DependencyObject
*obj
= (DependencyObject
*)value
;
145 NameScope
*scope
= (NameScope
*)user_data
;
147 scope
->RegisterName (name
, obj
);
150 struct DuplicatesData
{
152 bool duplicate_found
;
153 char *duplicate_name
;
157 look_for_duplicates (gpointer key
, gpointer value
, gpointer user_data
)
159 DuplicatesData
*data
= (DuplicatesData
*)user_data
;
161 if (data
->duplicate_found
)
164 char *name
= (char*)key
;
165 void *o
= data
->ns
->FindName (name
);
166 if (o
&& o
!= value
) {
167 data
->duplicate_found
= true;
168 data
->duplicate_name
= g_strdup (name
);
173 NameScope::MergeTemporaryScope (NameScope
*temp
, MoonError
*error
)
175 if (!temp
|| !temp
->names
)
180 data
.duplicate_found
= false;
181 data
.duplicate_name
= NULL
;
183 g_hash_table_foreach (temp
->names
, look_for_duplicates
, &data
);
184 if (data
.duplicate_found
) {
185 MoonError::FillIn (error
, MoonError::ARGUMENT
, 2028,
186 g_strdup_printf ("The name already exists in the tree: %s.",
187 data
.duplicate_name
));
188 g_free (data
.duplicate_name
);
192 g_hash_table_foreach (temp
->names
, merge_name
, this);
196 dump_namescope_helper (gpointer key
, gpointer value
, gpointer user_data
)
198 fprintf (stderr
, " %s => %s\n", (char*)key
, ((DependencyObject
*)value
)->GetTypeName());
205 fprintf (stderr
, " ns = %p\n", this);
206 g_hash_table_foreach (names
, dump_namescope_helper
, NULL
);