From 6db99bee2559c42da205d7d9e9cfe5edd6506cfb Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 28 Mar 2012 14:43:49 +0900 Subject: [PATCH] Don't enumerate over keys when find_by_keycode. --- eek/eek-keyboard.c | 68 ++++++++++++++++++++--------------------- eek/eek-section.c | 56 +++++++++------------------------ eek/eek-section.h | 7 ++--- eek/eek-xkb-layout.c | 3 +- eek/eek-xml-layout.c | 53 ++++++++++++++++---------------- tests/eek-simple-test.c | 4 +-- 6 files changed, 79 insertions(+), 112 deletions(-) diff --git a/eek/eek-keyboard.c b/eek/eek-keyboard.c index 35048533..d7be6001 100644 --- a/eek/eek-keyboard.c +++ b/eek/eek-keyboard.c @@ -68,6 +68,7 @@ struct _EekKeyboardPrivate GList *pressed_keys; GList *locked_keys; GArray *outline_array; + GHashTable *keycodes; /* modifiers dynamically assigned at run time */ EekModifierType num_lock_mask; @@ -139,6 +140,27 @@ on_symbol_index_changed (EekSection *section, g_signal_emit_by_name (keyboard, "symbol-index-changed", group, level); } +static void +section_child_added_cb (EekContainer *container, + EekElement *element, + EekKeyboard *keyboard) +{ + guint keycode = eek_key_get_keycode (EEK_KEY(element)); + g_hash_table_insert (keyboard->priv->keycodes, + GUINT_TO_POINTER(keycode), + element); +} + +static void +section_child_removed_cb (EekContainer *container, + EekElement *element, + EekKeyboard *keyboard) +{ + guint keycode = eek_key_get_keycode (EEK_KEY(element)); + g_hash_table_remove (keyboard->priv->keycodes, + GUINT_TO_POINTER(keycode)); +} + static EekSection * eek_keyboard_real_create_section (EekKeyboard *self) { @@ -147,43 +169,17 @@ eek_keyboard_real_create_section (EekKeyboard *self) section = g_object_new (EEK_TYPE_SECTION, NULL); g_return_val_if_fail (section, NULL); + g_signal_connect (G_OBJECT(section), "child-added", + G_CALLBACK(section_child_added_cb), self); + + g_signal_connect (G_OBJECT(section), "child-removed", + G_CALLBACK(section_child_removed_cb), self); + EEK_CONTAINER_GET_CLASS(self)->add_child (EEK_CONTAINER(self), EEK_ELEMENT(section)); return section; } -struct _FindKeyByKeycodeCallbackData { - EekKey *key; - guint keycode; -}; -typedef struct _FindKeyByKeycodeCallbackData FindKeyByKeycodeCallbackData; - -static gint -find_key_by_keycode_section_callback (EekElement *element, gpointer user_data) -{ - FindKeyByKeycodeCallbackData *data = user_data; - - data->key = eek_section_find_key_by_keycode (EEK_SECTION(element), - data->keycode); - if (data->key) - return 0; - return -1; -} - -static EekKey * -eek_keyboard_real_find_key_by_keycode (EekKeyboard *self, - guint keycode) -{ - FindKeyByKeycodeCallbackData data; - - data.keycode = keycode; - if (eek_container_find (EEK_CONTAINER(self), - find_key_by_keycode_section_callback, - &data)) - return data.key; - return NULL; -} - static void eek_keyboard_set_property (GObject *object, guint prop_id, @@ -375,6 +371,8 @@ eek_keyboard_finalize (GObject *object) g_list_free_full (priv->locked_keys, (GDestroyNotify) eek_modifier_key_free); + g_hash_table_destroy (priv->keycodes); + for (i = 0; i < priv->outline_array->len; i++) { EekOutline *outline = &g_array_index (priv->outline_array, EekOutline, @@ -427,7 +425,6 @@ eek_keyboard_class_init (EekKeyboardClass *klass) sizeof (EekKeyboardPrivate)); klass->create_section = eek_keyboard_real_create_section; - klass->find_key_by_keycode = eek_keyboard_real_find_key_by_keycode; /* signals */ klass->key_pressed = eek_keyboard_real_key_pressed; @@ -578,6 +575,7 @@ eek_keyboard_init (EekKeyboard *self) self->priv = EEK_KEYBOARD_GET_PRIVATE(self); self->priv->modifier_behavior = EEK_MODIFIER_BEHAVIOR_NONE; self->priv->outline_array = g_array_new (FALSE, TRUE, sizeof (EekOutline)); + self->priv->keycodes = g_hash_table_new (g_direct_hash, g_direct_equal); eek_element_set_symbol_index (EEK_ELEMENT(self), 0, 0); } @@ -609,8 +607,8 @@ eek_keyboard_find_key_by_keycode (EekKeyboard *keyboard, guint keycode) { g_return_val_if_fail (EEK_IS_KEYBOARD(keyboard), NULL); - return EEK_KEYBOARD_GET_CLASS(keyboard)-> - find_key_by_keycode (keyboard, keycode); + return g_hash_table_lookup (keyboard->priv->keycodes, + GUINT_TO_POINTER(keycode)); } /** diff --git a/eek/eek-section.c b/eek/eek-section.c index 868174ce..be208407 100644 --- a/eek/eek-section.c +++ b/eek/eek-section.c @@ -150,9 +150,10 @@ on_cancelled (EekKey *key, } static EekKey * -eek_section_real_create_key (EekSection *self, - gint column, - gint row) +eek_section_real_create_key (EekSection *self, + guint keycode, + gint column, + gint row) { EekKey *key; gint num_columns, num_rows; @@ -164,6 +165,7 @@ eek_section_real_create_key (EekSection *self, g_return_val_if_fail (column < num_columns, NULL); key = g_object_new (EEK_TYPE_KEY, + "keycode", keycode, "column", column, "row", row, NULL); @@ -175,23 +177,6 @@ eek_section_real_create_key (EekSection *self, return key; } -static gint -compare_key_by_keycode (EekElement *element, gpointer user_data) -{ - if (eek_key_get_keycode (EEK_KEY(element)) == (guint)(long)user_data) - return 0; - return -1; -} - -static EekKey * -eek_section_real_find_key_by_keycode (EekSection *self, - guint keycode) -{ - return (EekKey *)eek_container_find (EEK_CONTAINER(self), - compare_key_by_keycode, - (gpointer)(long)keycode); -} - static void set_level_from_modifiers (EekSection *self) { @@ -340,7 +325,6 @@ eek_section_class_init (EekSectionClass *klass) klass->add_row = eek_section_real_add_row; klass->get_row = eek_section_real_get_row; klass->create_key = eek_section_real_create_key; - klass->find_key_by_keycode = eek_section_real_find_key_by_keycode; /* signals */ klass->key_pressed = eek_section_real_key_pressed; @@ -563,6 +547,7 @@ eek_section_get_row (EekSection *section, /** * eek_section_create_key: * @section: an #EekSection + * @keycode: a keycode * @column: the column index of the key * @row: the row index of the key * @@ -571,27 +556,14 @@ eek_section_get_row (EekSection *section, * implementation. */ EekKey * -eek_section_create_key (EekSection *section, - gint column, - gint row) +eek_section_create_key (EekSection *section, + guint keycode, + gint column, + gint row) { g_return_val_if_fail (EEK_IS_SECTION(section), NULL); - return EEK_SECTION_GET_CLASS(section)->create_key (section, column, row); -} - -/** - * eek_section_find_key_by_keycode: - * @section: an #EekSection - * @keycode: a keycode - * - * Find an #EekKey whose keycode is @keycode. - * Returns: an #EekKey or NULL (if not found) - */ -EekKey * -eek_section_find_key_by_keycode (EekSection *section, - guint keycode) -{ - g_return_val_if_fail (EEK_IS_SECTION(section), NULL); - return EEK_SECTION_GET_CLASS(section)->find_key_by_keycode (section, - keycode); + return EEK_SECTION_GET_CLASS(section)->create_key (section, + keycode, + column, + row); } diff --git a/eek/eek-section.h b/eek/eek-section.h index a7bd5ad4..6392cdb2 100644 --- a/eek/eek-section.h +++ b/eek/eek-section.h @@ -61,8 +61,6 @@ struct _EekSection * @add_row: virtual function for adding a new row to the section * @get_row: virtual function for accessing a row in the section * @create_key: virtual function for creating key in the section - * @find_key_by_keycode: virtual function for accessing a key in the - * section by keycode * @key_pressed: class handler for #EekSection::key-pressed signal * @key_released: class handler for #EekSection::key-released signal * @key_locked: class handler for #EekSection::key-locked signal @@ -85,12 +83,10 @@ struct _EekSectionClass EekOrientation *orientation); EekKey *(* create_key) (EekSection *self, + guint keycode, gint row, gint column); - EekKey *(* find_key_by_keycode) (EekSection *self, - guint keycode); - /* signals */ void (* key_pressed) (EekSection *self, EekKey *key); @@ -124,6 +120,7 @@ void eek_section_get_row (EekSection *section, EekOrientation *orientation); EekKey *eek_section_create_key (EekSection *section, + guint keycode, gint column, gint row); diff --git a/eek/eek-xkb-layout.c b/eek/eek-xkb-layout.c index 3b3e6c1b..4e37e68e 100644 --- a/eek/eek-xkb-layout.c +++ b/eek/eek-xkb-layout.c @@ -222,10 +222,9 @@ create_key (EekXkbLayout *layout, } } - key = eek_section_create_key (section, column, row); + key = eek_section_create_key (section, keycode, column, row); eek_element_set_name (EEK_ELEMENT(key), name); eek_element_set_bounds (EEK_ELEMENT(key), &bounds); - eek_key_set_keycode (key, keycode); eek_key_set_symbol_matrix (key, matrix); eek_symbol_matrix_free (matrix); eek_key_set_oref (key, oref); diff --git a/eek/eek-xml-layout.c b/eek/eek-xml-layout.c index 43e681a3..8493ced9 100644 --- a/eek/eek-xml-layout.c +++ b/eek/eek-xml-layout.c @@ -401,31 +401,8 @@ geometry_start_element_callback (GMarkupParseContext *pcontext, } if (g_strcmp0 (element_name, "key") == 0) { - guint column, row; - - attribute = get_attribute (attribute_names, attribute_values, - "column"); - if (attribute == NULL) { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_MISSING_ATTRIBUTE, - "no \"column\" attribute for \"key\""); - return; - } - column = strtoul (attribute, NULL, 10); - - attribute = get_attribute (attribute_names, attribute_values, - "row"); - if (attribute == NULL) { - g_set_error (error, - G_MARKUP_ERROR, - G_MARKUP_ERROR_MISSING_ATTRIBUTE, - "no \"row\" attribute for \"row\""); - return; - } - row = strtoul (attribute, NULL, 10); - - data->key = eek_section_create_key (data->section, column, row); + guint keycode; + gint column, row; attribute = get_attribute (attribute_names, attribute_values, "keycode"); @@ -436,7 +413,31 @@ geometry_start_element_callback (GMarkupParseContext *pcontext, "no \"keycode\" attribute for \"key\""); return; } - eek_key_set_keycode (data->key, strtoul (attribute, NULL, 10)); + keycode = strtoul (attribute, NULL, 10); + + attribute = get_attribute (attribute_names, attribute_values, + "column"); + if (attribute == NULL) { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_MISSING_ATTRIBUTE, + "no \"column\" attribute for \"key\""); + return; + } + column = strtol (attribute, NULL, 10); + + attribute = get_attribute (attribute_names, attribute_values, + "row"); + if (attribute == NULL) { + g_set_error (error, + G_MARKUP_ERROR, + G_MARKUP_ERROR_MISSING_ATTRIBUTE, + "no \"row\" attribute for \"row\""); + return; + } + row = strtol (attribute, NULL, 10); + + data->key = eek_section_create_key (data->section, keycode, column, row); attribute = get_attribute (attribute_names, attribute_values, "name"); diff --git a/tests/eek-simple-test.c b/tests/eek-simple-test.c index 59e441fe..b2597b7c 100644 --- a/tests/eek-simple-test.c +++ b/tests/eek-simple-test.c @@ -30,9 +30,9 @@ test_create (void) section = eek_keyboard_create_section (keyboard); g_assert (EEK_IS_SECTION(section)); eek_section_add_row (section, 2, EEK_ORIENTATION_HORIZONTAL); - key0 = eek_section_create_key (section, 0, 0); + key0 = eek_section_create_key (section, 1, 0, 0); g_assert (EEK_IS_KEY(key0)); - key1 = eek_section_create_key (section, 1, 0); + key1 = eek_section_create_key (section, 2, 1, 0); g_assert (EEK_IS_KEY(key1)); }