From 700d87b3709c5eeb6fa7a238b24ae93e6fad4d68 Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Wed, 22 Jan 2020 11:33:41 +0900 Subject: [PATCH 01/12] Revert "efl_mono: remove class ExtensionTag" Extension Methods' classes have methods with same names and parameters. e.g. Text(this Efl.Ui.ItemFactory fac) Although the where clause contains different classes, they cannot be identified as different methods by C# compiler. e.g. Text(this Efl.Ui.ItemFactory fac) where T : Efl.Ui.Button e.g. Text(this Efl.Ui.ItemFactory fac) where T : Efl.Ui.Check As a result, to avoid ambiguous methods, ExtensionTag should be used as a second parameter of each method. e.g. Text(this Efl.Ui.ItemFactory fac, ExtensionTagmagic = null) where T : Efl.Ui.Button e.g. Text(this Efl.Ui.ItemFactory fac, ExtensionTagmagic = null) where T : Efl.Ui.Check This reverts commit 76631f502a8234c04ed8124bfdebe62ed5bdf954. --- .../eolian_mono/eolian/mono/function_definition.hh | 10 ++++++---- src/bin/eolian_mono/eolian/mono/part_definition.hh | 5 +++-- src/bindings/mono/efl_mono/Bind.cs | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/function_definition.hh b/src/bin/eolian_mono/eolian/mono/function_definition.hh index fcc8a88f15..3c30cdd3fe 100644 --- a/src/bin/eolian_mono/eolian/mono/function_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/function_definition.hh @@ -284,8 +284,9 @@ struct property_extension_method_definition_generator if (property.setter.is_engaged()) { attributes::type_def prop_type = property.setter->parameters[0].type; - if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "(this Efl.Ui.ItemFactory fac) where T : " - << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n" + if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "(this Efl.Ui.ItemFactory fac, Efl.Csharp.ExtensionTag<" + << name_helpers::klass_full_concrete_or_interface_name(cls) + << ", T>magic = null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n" << scope_tab(2) << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(\"" << property.name << "\", fac);\n" << scope_tab(2) << "}\n\n" ).generate(sink, std::make_tuple(prop_type, prop_type), context)) @@ -300,8 +301,9 @@ struct property_extension_method_definition_generator if (property.setter.is_engaged()) { attributes::type_def prop_type = property.setter->parameters[0].type; - if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "(this Efl.BindablePart part) where T : " - << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n" + if (!as_generator(scope_tab(2) << "public static Efl.BindableProperty<" << type(true) << "> " << managed_name << "(this Efl.BindablePart part, Efl.Csharp.ExtensionTag<" + << name_helpers::klass_full_concrete_or_interface_name(cls) + << ", T>magic = null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << " {\n" << scope_tab(2) << scope_tab << "Contract.Requires(part != null, nameof(part));\n" << scope_tab(2) << scope_tab << "return new Efl.BindableProperty<" << type(true) << ">(part.PartName, \"" << property.name << "\", part.Binder);\n" << scope_tab(2) << "}\n\n" diff --git a/src/bin/eolian_mono/eolian/mono/part_definition.hh b/src/bin/eolian_mono/eolian/mono/part_definition.hh index d87b0b56ac..4facf27209 100644 --- a/src/bin/eolian_mono/eolian/mono/part_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/part_definition.hh @@ -70,8 +70,9 @@ struct part_extension_method_definition_generator bindableClass = "Efl.BindableFactoryPart"; if (!as_generator( - scope_tab(2) << "public static " << bindableClass << "<" << part_klass_name << "> " << name_helpers::managed_part_name(part) << "(this Efl.Ui.ItemFactory fac) where T : " - << name_helpers::klass_full_concrete_or_interface_name(cls) << "\n" + scope_tab(2) << "public static " << bindableClass << "<" << part_klass_name << "> " << name_helpers::managed_part_name(part) << "(this Efl.Ui.ItemFactory fac, Efl.Csharp.ExtensionTag<" + << name_helpers::klass_full_concrete_or_interface_name(cls) + << ", T> x=null) where T : " << name_helpers::klass_full_concrete_or_interface_name(cls) << "\n" << scope_tab(2) << "{\n" << scope_tab(2) << scope_tab << "return new " << bindableClass << "<" << part_klass_name << ">(\"" << part.name << "\", fac);\n" << scope_tab(2) << "}\n\n" diff --git a/src/bindings/mono/efl_mono/Bind.cs b/src/bindings/mono/efl_mono/Bind.cs index 302f1dadd2..2a4fcbded5 100644 --- a/src/bindings/mono/efl_mono/Bind.cs +++ b/src/bindings/mono/efl_mono/Bind.cs @@ -148,6 +148,20 @@ public class BindableFactoryPart } } +namespace Csharp +{ + +/// Helper class to differentiate between factory extension methods. +/// +/// For internal use only. +[EditorBrowsable(EditorBrowsableState.Never)] +public class ExtensionTag + where TInherited : TBase +{ +} + +} + } #endif From f1740535648a4d1c8d372376a727d23e61c68c5d Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Wed, 22 Jan 2020 07:37:11 -0500 Subject: [PATCH 02/12] ecore_wl2: Add ecore_wl2_input_keyboard_repeat_set() API. Summary: Add API to set input's keyboard repeat. get API was already there. Reviewers: devilhorns Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D11131 --- src/lib/ecore_wl2/Ecore_Wl2.h | 11 +++++++++++ src/lib/ecore_wl2/ecore_wl2_input.c | 20 ++++++++++++++++++-- src/lib/ecore_wl2/ecore_wl2_private.h | 1 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 6a54812204..eed6660c7e 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -1448,6 +1448,17 @@ EAPI Eina_Stringshare *ecore_wl2_input_name_get(Ecore_Wl2_Input *input); */ EAPI Eina_Bool ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay); +/** + * Set the keyboard repeat rate and delay of an input + * @param input The input + * @param rate Pointer to store the repeat rate (in seconds) + * @param rate Pointer to store the repeat delay (in seconds) + * @return True if repeat is enabled + * @ingroup Ecore_Wl2_Input_Group + * @since 1.24 + */ +EAPI Eina_Bool ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input *input, double rate, double delay); + /** * Retrieves the mouse position of the seat * diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 6694f3687d..92cc9a52bd 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -1173,8 +1173,11 @@ _keyboard_cb_repeat_setup(void *data, struct wl_keyboard *keyboard EINA_UNUSED, } input->repeat.enabled = EINA_TRUE; - input->repeat.rate = (1.0 / rate); - input->repeat.delay = (delay / 1000.0); + if (!input->repeat.changed) + { + input->repeat.rate = (1.0 / rate); + input->repeat.delay = (delay / 1000.0); + } ev = malloc(sizeof(Ecore_Wl2_Event_Seat_Keymap_Changed)); if (ev) { @@ -1615,6 +1618,7 @@ _ecore_wl2_input_add(Ecore_Wl2_Display *display, unsigned int id, unsigned int v input->repeat.rate = 0.025; input->repeat.delay = 0.4; input->repeat.enabled = EINA_TRUE; + input->repeat.changed = EINA_FALSE; wl_array_init(&input->data.selection.types); wl_array_init(&input->data.drag.types); @@ -1813,6 +1817,18 @@ ecore_wl2_input_keymap_get(const Ecore_Wl2_Input *input) return input->xkb.keymap; } +EAPI Eina_Bool +ecore_wl2_input_keyboard_repeat_set(Ecore_Wl2_Input *input, double rate, double delay) +{ + EINA_SAFETY_ON_NULL_RETURN_VAL(input, EINA_FALSE); + EINA_SAFETY_ON_NULL_RETURN_VAL(input->display, EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(input->wl.keyboard, EINA_FALSE); + input->repeat.rate = rate; + input->repeat.delay = delay; + input->repeat.changed = EINA_TRUE; + return input->repeat.enabled; +} + EAPI Eina_Bool ecore_wl2_input_keyboard_repeat_get(const Ecore_Wl2_Input *input, double *rate, double *delay) { diff --git a/src/lib/ecore_wl2/ecore_wl2_private.h b/src/lib/ecore_wl2/ecore_wl2_private.h index 5178e8f3ea..0f8b7ffc09 100644 --- a/src/lib/ecore_wl2/ecore_wl2_private.h +++ b/src/lib/ecore_wl2/ecore_wl2_private.h @@ -508,6 +508,7 @@ struct _Ecore_Wl2_Input double rate, delay; Eina_Bool enabled : 1; Eina_Bool repeating : 1; + Eina_Bool changed : 1; } repeat; struct From 46cfcf71903aea7422897eb66a2a5fa0c70f5bfa Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Wed, 22 Jan 2020 07:37:23 -0500 Subject: [PATCH 03/12] ecore_wl2: Add ecore_wl2_input_default_input_get() API. Summary: Gets default input which created by display. Reviewers: devilhorns Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D11132 --- src/lib/ecore_wl2/Ecore_Wl2.h | 25 +++++++++++++++++++++++++ src/lib/ecore_wl2/ecore_wl2_input.c | 14 ++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index eed6660c7e..294af10b5a 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -1485,6 +1485,31 @@ EAPI Eina_Bool ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int */ EAPI void ecore_wl2_input_pointer_set(Ecore_Wl2_Input *input, struct wl_surface *surface, int hot_x, int hot_y); +/** + * Set a specific cursor on a given seat + * + * @brief This function will try to find a matching cursor inside the existing + * cursor theme and set the pointer for the specified seat to be + * the specified cursor + * + * @param input The seat to set the cursor on + * @param cursor The name of the cursor to try and set + * + * @ingroup Ecore_Wl2_Input_Group + * @since 1.20 + */ +EAPI void ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor); + +/** + * Gets default input of a given display + * + * @param display The display + * + * @ingroup Ecore_Wl2_Input_Group + * @since 1.24 + */ +EAPI Ecore_Wl2_Input *ecore_wl2_input_default_input_get(const Ecore_Wl2_Display *ewd); + /** * @defgroup Ecore_Wl2_Output_Group Wayland Library Output Functions * @ingroup Ecore_Wl2_Group diff --git a/src/lib/ecore_wl2/ecore_wl2_input.c b/src/lib/ecore_wl2/ecore_wl2_input.c index 92cc9a52bd..75a7366f82 100644 --- a/src/lib/ecore_wl2/ecore_wl2_input.c +++ b/src/lib/ecore_wl2/ecore_wl2_input.c @@ -1871,3 +1871,17 @@ ecore_wl2_input_pointer_xy_get(const Ecore_Wl2_Input *input, int *x, int *y) if (y) *y = input->pointer.sy; return EINA_TRUE; } + +EAPI Ecore_Wl2_Input * +ecore_wl2_input_default_input_get(const Ecore_Wl2_Display *ewd) +{ + Ecore_Wl2_Input *input; + + EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL); + EINA_SAFETY_ON_NULL_RETURN_VAL(ewd->inputs, NULL); + + input = ecore_wl2_display_input_find_by_name(ewd, "seat0"); + if (!input) input = ecore_wl2_display_input_find_by_name(ewd, "default"); + + return input; +} From e23dc58e200e89ed2eb72ee9931e0f1db83bfddf Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Wed, 22 Jan 2020 07:39:48 -0500 Subject: [PATCH 04/12] Revert "ecore-wl2: Move ecore_wl2_input_cursor_from_name_set to be internal" Summary: This reverts commit 6a1d6b6705911dca8e9facc0fefc55e02c6e3694. This API is used publicly in Tizen, so we cannot make it internal. ref T8016 Reviewers: devilhorns Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T8016 Differential Revision: https://phab.enlightenment.org/D11147 --- src/lib/ecore_wl2/ecore_wl2_internal.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/lib/ecore_wl2/ecore_wl2_internal.h b/src/lib/ecore_wl2/ecore_wl2_internal.h index 111b2cad30..03d5e27b92 100644 --- a/src/lib/ecore_wl2/ecore_wl2_internal.h +++ b/src/lib/ecore_wl2/ecore_wl2_internal.h @@ -579,21 +579,6 @@ EAPI void ecore_wl2_window_aux_hint_del(Ecore_Wl2_Window *window, int id); */ EAPI void ecore_wl2_display_terminate(Ecore_Wl2_Display *display); -/** - * Set a specific cursor on a given seat - * - * @brief This function will try to find a matching cursor inside the existing - * cursor theme and set the pointer for the specified seat to be - * the specified cursor - * - * @param input The seat to set the cursor on - * @param cursor The name of the cursor to try and set - * - * @ingroup Ecore_Wl2_Input_Group - * @since 1.20 - */ -EAPI void ecore_wl2_input_cursor_from_name_set(Ecore_Wl2_Input *input, const char *cursor); - # undef EAPI # define EAPI From 0bf03036b7c395b5d7d54340e25783c5b920a984 Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Wed, 22 Jan 2020 07:41:39 -0500 Subject: [PATCH 05/12] tests/ecore_wl2: Add tests for move, resize, resizing_get functions. Summary: Add ecore_wl2_window_move ecore_wl2_window_resize ecore_wl2_window_resizing_get ref T8016 Reviewers: devilhorns Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T8016 Differential Revision: https://phab.enlightenment.org/D11150 --- src/tests/ecore_wl2/ecore_wl2_test_window.c | 54 +++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/tests/ecore_wl2/ecore_wl2_test_window.c b/src/tests/ecore_wl2/ecore_wl2_test_window.c index b166b4ba4e..ab60ac2077 100644 --- a/src/tests/ecore_wl2/ecore_wl2_test_window.c +++ b/src/tests/ecore_wl2/ecore_wl2_test_window.c @@ -883,6 +883,57 @@ EFL_START_TEST(wl2_window_update_begin) } EFL_END_TEST +EFL_START_TEST(wl2_window_move) +{ + Ecore_Wl2_Display *disp; + Ecore_Wl2_Window *win; + + disp = _display_connect(); + ck_assert(disp != NULL); + + win = _window_create(disp); + ck_assert(win != NULL); + + //FIXME: Need some discussion about how to validate this API in TC. + ecore_wl2_window_move(NULL, NULL); + ecore_wl2_window_move(win, NULL); +} +EFL_END_TEST + +EFL_START_TEST(wl2_window_resize) +{ + Ecore_Wl2_Display *disp; + Ecore_Wl2_Window *win; + + disp = _display_connect(); + ck_assert(disp != NULL); + + win = _window_create(disp); + ck_assert(win != NULL); + + //FIXME: Need some discussion about how to validate this API in TC. + ecore_wl2_window_resize(NULL, NULL, 0); + ecore_wl2_window_resize(win, NULL, 0); +} +EFL_END_TEST + +EFL_START_TEST(wl2_window_resizing_get) +{ + Ecore_Wl2_Display *disp; + Ecore_Wl2_Window *win; + Eina_Bool ret; + + disp = _display_connect(); + ck_assert(disp != NULL); + + win = _window_create(disp); + ck_assert(win != NULL); + + ret = ecore_wl2_window_resizing_get(win); + fail_if (ret == EINA_TRUE); +} +EFL_END_TEST + void ecore_wl2_test_window(TCase *tc) { @@ -922,5 +973,8 @@ ecore_wl2_test_window(TCase *tc) tcase_add_test(tc, wl2_window_input_region); tcase_add_test(tc, wl2_window_opaque_region); tcase_add_test(tc, wl2_window_popup_input); + tcase_add_test(tc, wl2_window_move); + tcase_add_test(tc, wl2_window_resize); + tcase_add_test(tc, wl2_window_resizing_get); } } From bcff657ed7abfc5b246620cb0ef2c0b5874106c8 Mon Sep 17 00:00:00 2001 From: Woochanlee Date: Wed, 22 Jan 2020 07:41:58 -0500 Subject: [PATCH 06/12] Revert "ecore-wl2: Move ecore_wl2_window_output_find function to be internal" Summary: This reverts commit 64dacb3d07f6ed74a53e4e38c25e27ebd9bfb6f7. User can't use ecore_wl2_output_dpi_get() , ecore_wl2_output_transform_get() APIs without this API. Reviewers: devilhorns Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D11154 --- src/lib/ecore_wl2/Ecore_Wl2.h | 12 ++++++++++++ src/lib/ecore_wl2/ecore_wl2_internal.h | 12 ------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 294af10b5a..da664939b7 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -1120,6 +1120,18 @@ EAPI void ecore_wl2_window_type_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window_T */ EAPI Ecore_Wl2_Window_Type ecore_wl2_window_type_get(Ecore_Wl2_Window *window); +/** + * Find the output that a given window is on + * + * @param window The window to find the output for + * + * @return An Ecore_Wl2_Output if found, or NULL otherwise + * + * @ingroup Ecore_Wl2_Window_Group + * @since 1.20 + */ +EAPI Ecore_Wl2_Output *ecore_wl2_window_output_find(Ecore_Wl2_Window *window); + /** * Set if window rotation is supported by the window manager * diff --git a/src/lib/ecore_wl2/ecore_wl2_internal.h b/src/lib/ecore_wl2/ecore_wl2_internal.h index 03d5e27b92..98dd5c1b5a 100644 --- a/src/lib/ecore_wl2/ecore_wl2_internal.h +++ b/src/lib/ecore_wl2/ecore_wl2_internal.h @@ -125,18 +125,6 @@ EAPI void ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool ico */ EAPI Eina_Bool ecore_wl2_window_pending_get(Ecore_Wl2_Window *window); -/** - * Find the output that a given window is on - * - * @param window The window to find the output for - * - * @return An Ecore_Wl2_Output if found, or NULL otherwise - * - * @ingroup Ecore_Wl2_Window_Group - * @since 1.20 - */ -EAPI Ecore_Wl2_Output *ecore_wl2_window_output_find(Ecore_Wl2_Window *window); - /** * @defgroup Ecore_Wl2_Dnd_Group Wayland Library Drag-n-Drop Functions * @ingroup Ecore_Wl2_Group From 55118cac119df8d2823c3f33e88fdc9bee9e6643 Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Wed, 22 Jan 2020 08:37:33 -0500 Subject: [PATCH 07/12] tests/ecore_wl2: Add test for ecore_wl2_input_keyboard_repeat functions ref T8016 --- src/tests/ecore_wl2/ecore_wl2_test_input.c | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/tests/ecore_wl2/ecore_wl2_test_input.c b/src/tests/ecore_wl2/ecore_wl2_test_input.c index 3c0330a3c8..2802ee6c00 100644 --- a/src/tests/ecore_wl2/ecore_wl2_test_input.c +++ b/src/tests/ecore_wl2/ecore_wl2_test_input.c @@ -197,6 +197,36 @@ EFL_START_TEST(wl2_input_pointer_xy) } EFL_END_TEST +EFL_START_TEST(wl2_input_keyboard_repeat) +{ + Ecore_Wl2_Display *disp; + Ecore_Wl2_Input *input; + Eina_Iterator *itr; + + disp = _display_connect(); + ck_assert(disp != NULL); + + itr = ecore_wl2_display_inputs_get(disp); + ck_assert(itr != NULL); + + EINA_ITERATOR_FOREACH(itr, input) + { + if (ecore_wl2_input_seat_capabilities_get(input) == + ECORE_WL2_SEAT_CAPABILITIES_KEYBOARD) + { + double rate = 0.0, delay = 0.0; + + ecore_wl2_input_keyboard_repeat_set(input, 2.0, 2.0); + ecore_wl2_input_keyboard_repeat_get(input, &rate, &delay); + ck_assert_double_ne(rate, 2.0); + ck_assert_double_ne(delay, 2.0); + } + } + + eina_iterator_free(itr); +} +EFL_END_TEST + void ecore_wl2_test_input(TCase *tc) { @@ -209,5 +239,6 @@ ecore_wl2_test_input(TCase *tc) tcase_add_test(tc, wl2_input_name_get); tcase_add_test(tc, wl2_input_seat_capabilities); tcase_add_test(tc, wl2_input_pointer_xy); + tcase_add_test(tc, wl2_input_keyboard_repeat); } } From baa787008269a26f79dc1f95f4d0ce0d9d16a204 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Fri, 17 Jan 2020 14:40:58 +0100 Subject: [PATCH 08/12] evas_object_box: fix invalidator the iteration over the content of the box did never cleanup the children pointer, which resulted in buggy behavior. This fixes test suite crashes with freeq debugging on. Reviewed-by: Mike Blumenkrantz Differential Revision: https://phab.enlightenment.org/D11123 --- src/lib/evas/canvas/evas_object_box.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_box.c b/src/lib/evas/canvas/evas_object_box.c index 7a7173eb25..7853ee3e10 100644 --- a/src/lib/evas/canvas/evas_object_box.c +++ b/src/lib/evas/canvas/evas_object_box.c @@ -412,18 +412,16 @@ _evas_box_efl_canvas_group_group_add(Eo *eo_obj, Evas_Object_Box_Data *priv) EOLIAN static void _evas_box_efl_canvas_group_group_del(Eo *o, Evas_Object_Box_Data *priv) { - Eina_List *l; - - l = priv->children; - while (l) + while (priv->children) { - Evas_Object_Box_Option *opt = l->data; + Evas_Object_Box_Option *opt = eina_list_data_get(priv->children); _evas_object_box_child_callbacks_unregister(opt->obj, o); evas_obj_box_internal_option_free(o, opt); - l = eina_list_remove_list(l, l); + priv->children = eina_list_remove_list(priv->children, priv->children); } + if (priv->layout.data && priv->layout.free_data) priv->layout.free_data(priv->layout.data); From 93bd97025983e48ae8048d0c63b5d8b314f1de42 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 22 Jan 2020 11:57:26 -0500 Subject: [PATCH 09/12] efl_ui_image: Call unload file when calling file_set Summary: We have checked that unload is not called even if different files call again elm_image_file_set on the same object. If file_set is called repeatedly, I think a potential error can occur. So, modify to call unload when doing file_set by referring to efl_ui_zoomable. Test Plan: N/A Reviewers: Hermet, zmike Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D11148 --- src/lib/elementary/efl_ui_image.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/elementary/efl_ui_image.c b/src/lib/elementary/efl_ui_image.c index 1f6ba219d1..1de73161c5 100644 --- a/src/lib/elementary/efl_ui_image.c +++ b/src/lib/elementary/efl_ui_image.c @@ -999,6 +999,7 @@ _efl_ui_image_smart_internal_file_set(Eo *obj, Efl_Ui_Image_Data *sd) const Eina_File *f; const char *key; const char *file = efl_file_get(obj); + efl_file_unload(obj); if (eina_str_has_extension(file, ".edj")) return _efl_ui_image_edje_file_set(obj); From 5137f6d143c681fcf4f53e4e45df8af1a538ae75 Mon Sep 17 00:00:00 2001 From: ali Date: Thu, 23 Jan 2020 06:54:44 +0900 Subject: [PATCH 10/12] eina: add new range Data type Summary: Introduce new data type (Eina.Range) which represent range (part of series) **eina_range_max_get** **eina_range_intersect** **eina_range_union** **eina_range_contains** **eina_range_equal** Reviewers: cedric, woohyun, bu5hm4n, segfaultxavi, zmike Reviewed By: woohyun Subscribers: vtorri, cedric, #committers, #reviewers Tags: #efl Maniphest Tasks: T8570 Differential Revision: https://phab.enlightenment.org/D11133 --- src/lib/eina/Eina.h | 1 + src/lib/eina/eina_inline_range.x | 82 ++++++++++++++++++++++ src/lib/eina/eina_range.h | 116 +++++++++++++++++++++++++++++++ src/lib/eina/meson.build | 2 + src/lib/eo/eina_types.eot | 6 ++ src/tests/eina/eina_suite.c | 1 + src/tests/eina/eina_suite.h | 1 + src/tests/eina/eina_test_range.c | 72 +++++++++++++++++++ src/tests/eina/meson.build | 1 + 9 files changed, 282 insertions(+) create mode 100644 src/lib/eina/eina_inline_range.x create mode 100644 src/lib/eina/eina_range.h create mode 100644 src/tests/eina/eina_test_range.c diff --git a/src/lib/eina/Eina.h b/src/lib/eina/Eina.h index bbf3161929..9e3345e432 100644 --- a/src/lib/eina/Eina.h +++ b/src/lib/eina/Eina.h @@ -212,6 +212,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/src/lib/eina/eina_inline_range.x b/src/lib/eina/eina_inline_range.x new file mode 100644 index 0000000000..b5af9d7226 --- /dev/null +++ b/src/lib/eina/eina_inline_range.x @@ -0,0 +1,82 @@ +/* EINA - EFL data type library + * Copyright (C) 2020 Ali Alzyod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ +#ifndef EINA_INLINE_RANGE_H_ +#define EINA_INLINE_RANGE_H_ + +/*============================================================================* + * API * + *============================================================================*/ + +static inline size_t eina_range_end(const Eina_Range *range) +{ + if (range) return range->start + range->length; + return 0; +} + +static inline Eina_Range eina_range_intersect(const Eina_Range *range, const Eina_Range *range2) +{ + Eina_Range ret_range = EINA_RANGE_EMPTY(); + size_t min, max; + + if (!range || !range2) + return ret_range; + + min = MAX(range->start, range2->start); + max = MIN(range->start + range->length, range2->start + range2->length); + + if (max > min) + { + ret_range = eina_range_from_to(min, max); + } + + return ret_range; +} + +static inline Eina_Range eina_range_union(const Eina_Range *range, const Eina_Range *range2) +{ + size_t min, max; + + if (!range || !range2) + return EINA_RANGE_EMPTY(); + + min = MIN(range->start, range2->start); + max = MAX(range->start + range->length, range2->start + range2->length); + + return eina_range_from_to(min, max); +} + +static inline Eina_Bool eina_range_contains(const Eina_Range *range, size_t value) +{ + if (!range) return EINA_FALSE; + + return value >= range->start && value < (range->start + range->length); +} + +static inline Eina_Bool eina_range_equal(const Eina_Range *range, const Eina_Range *range2) +{ + if (!range || !range2) return EINA_FALSE; + return (range->start == range2->start && range->length == range2->length); +} + +static inline Eina_Range eina_range_from_to(size_t min, size_t max) +{ + if (min < max) return EINA_RANGE(min, max - min); + return EINA_RANGE(max, min - max);; +} + +#endif // EINA_INLINE_RANGE_H_ \ No newline at end of file diff --git a/src/lib/eina/eina_range.h b/src/lib/eina/eina_range.h new file mode 100644 index 0000000000..b5ffac92f1 --- /dev/null +++ b/src/lib/eina/eina_range.h @@ -0,0 +1,116 @@ +/* EINA - EFL data type library + * Copyright (C) 2020 Ali Alzyod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifndef EINA_RANGE_H_ +#define EINA_RANGE_H_ + +#include "eina_types.h" + +#include "eina_cpu.h" + +#define EINA_RANGE(start, length) ((Eina_Range) { (start), (length) }) +#define EINA_RANGE_FROM_TO(from, to) ((Eina_Range) { MIN((from),(to)), ABS((to) - (from)) }) +#define EINA_RANGE_ZERO() EINA_RANGE(0, 0) +#define EINA_RANGE_EMPTY() ((Eina_Range) EINA_RANGE_ZERO()) + +/** @brief A Int range */ +typedef struct _Eina_Range +{ + size_t start; + size_t length; +} Eina_Range; + + +/** + * @brief convenience macro for comparing two Eina_Range structs + * @param[in] a An Eina_Range + * @param[in] b An Eina_Range + * @return 1 if the structs are equal, 0 if they are not + * @since 1.24 + */ +#define EINA_RANGE_EQ(a, b) \ + (((a).start == (b).start) && ((a).length == (b).length)) + +/** + * @brief Get end value in range (not included in range). + * + * @param[in] range The Range. + * @return The sum of end and length of the range. + * + * @since 1.24 + * */ +static inline size_t eina_range_end(const Eina_Range *range); + +/** + * @brief Intersection between two ranges. + * + * @param[in] range The first range. + * @param[in] range2 The second range. + * @return The intersection between two ranges, If ranges do not intersect return length will be 0. + * + * @since 1.24 + * */ +static inline Eina_Range eina_range_intersect(const Eina_Range *range, const Eina_Range *range2); + + +/** + * @brief Union between two ranges. + * + * @param[in] range The first range. + * @param[in] range2 The second range. + * @return The union between two ranges. + * + * @since 1.24 + * */ +static inline Eina_Range eina_range_union(const Eina_Range *range, const Eina_Range *range2); + +/** + * @brief Check if value is set in a range. + * + * @param[in] range The range. + * @return Wither value set within range. + * + * @since 1.24 + * */ +static inline Eina_Bool eina_range_contains(const Eina_Range *range, size_t value); + +/** + * @brief Check if two ranges are equal. + * + * @param[in] range The first range. + * @param[in] range2 The second range. + * @return Wither two ranges are equal. + * + * @since 1.24 + * */ +static inline Eina_Bool eina_range_equal(const Eina_Range *range, const Eina_Range *range2); + +/** + * @brief Check if two ranges are equal. + * + * @param[in] min The min value in range. + * @param[in] max The max value in range. + * @return range. + * + * @since 1.24 + * */ +static inline Eina_Range eina_range_from_to(size_t min, size_t max); + +#include "eina_inline_range.x" + +#endif /*EINA_RANGE_H_*/ diff --git a/src/lib/eina/meson.build b/src/lib/eina/meson.build index 7866323742..97e1669c4f 100644 --- a/src/lib/eina/meson.build +++ b/src/lib/eina/meson.build @@ -32,6 +32,7 @@ public_sub_headers = [ 'eina_mempool.h', 'eina_module.h', 'eina_rectangle.h', +'eina_range.h', 'eina_types.h', 'eina_array.h', 'eina_counter.h', @@ -51,6 +52,7 @@ public_sub_headers = [ 'eina_inline_rbtree.x', 'eina_inline_mempool.x', 'eina_inline_rectangle.x', +'eina_inline_range.x', 'eina_inline_trash.x', 'eina_thread.h', 'eina_trash.h', diff --git a/src/lib/eo/eina_types.eot b/src/lib/eo/eina_types.eot index 4cb8e9347d..d4033e26aa 100644 --- a/src/lib/eo/eina_types.eot +++ b/src/lib/eo/eina_types.eot @@ -60,6 +60,12 @@ struct @extern Eina.Matrix3 { zz: double; [[ZZ matrix value]] } +struct @extern @beta Eina.Range { + [[A range sequence of values.]] + start: size; [[Start of the range.]] + length: size; [[Length of the range.]] +} + type @extern Eina.Unicode: uint32; [[Eina unicode type. @since 1.24]] struct @extern @beta Eina.File_Direct_Info; [[Eina file direct information data structure]] diff --git a/src/tests/eina/eina_suite.c b/src/tests/eina/eina_suite.c index dfa2bd1e5f..45316bd462 100644 --- a/src/tests/eina/eina_suite.c +++ b/src/tests/eina/eina_suite.c @@ -57,6 +57,7 @@ static const Efl_Test_Case etc[] = { { "Benchmark", eina_test_benchmark }, { "Mempool", eina_test_mempool }, { "Rectangle", eina_test_rectangle }, + { "Range", eina_test_range }, { "MatrixSparse", eina_test_matrixsparse }, { "Tiler", eina_test_tiler }, { "Strbuf", eina_test_strbuf }, diff --git a/src/tests/eina/eina_suite.h b/src/tests/eina/eina_suite.h index 5e7a1bf30f..102de63193 100644 --- a/src/tests/eina/eina_suite.h +++ b/src/tests/eina/eina_suite.h @@ -45,6 +45,7 @@ void eina_test_file(TCase *tc); void eina_test_benchmark(TCase *tc); void eina_test_mempool(TCase *tc); void eina_test_rectangle(TCase *tc); +void eina_test_range(TCase *tc); void eina_test_matrixsparse(TCase *tc); void eina_test_tiler(TCase *tc); void eina_test_strbuf(TCase *tc); diff --git a/src/tests/eina/eina_test_range.c b/src/tests/eina/eina_test_range.c new file mode 100644 index 0000000000..a1f84b8a00 --- /dev/null +++ b/src/tests/eina/eina_test_range.c @@ -0,0 +1,72 @@ +/* EINA - EFL data type library + * Copyright (C) 2020 Ali Alzyod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; + * if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +#include "eina_suite.h" + +EFL_START_TEST(eina_range_intersect_union_test) +{ + Eina_Range r1 = EINA_RANGE(0, 10); + Eina_Range r2 = EINA_RANGE(5, 15); + + Eina_Range r_intersect = eina_range_intersect(&r1, &r2); + ck_assert_uint_eq(r_intersect.start, 5); + ck_assert_uint_eq(r_intersect.length, 5); + + Eina_Range r_union = eina_range_union(&r1, &r2); + ck_assert_uint_eq(r_union.start, 0); + ck_assert_uint_eq(r_union.length, 20); +} +EFL_END_TEST + +EFL_START_TEST(eina_range_contains_test) +{ + Eina_Range r1 = EINA_RANGE(0, 10); + + ck_assert(eina_range_contains(&r1,0)); + ck_assert(eina_range_contains(&r1,9)); + ck_assert(!eina_range_contains(&r1,10)); +} +EFL_END_TEST + +EFL_START_TEST(eina_range_equal_test) +{ + Eina_Range r1 = EINA_RANGE(0, 10); + Eina_Range r2 = EINA_RANGE(0, 10); + Eina_Range r3 = EINA_RANGE(0, 9); + + ck_assert(eina_range_equal(&r1, &r2)); + ck_assert(!eina_range_equal(&r1, &r3)); +} +EFL_END_TEST + + +void +eina_test_range(TCase *tc) +{ + tcase_add_test(tc, eina_range_intersect_union_test); + tcase_add_test(tc, eina_range_contains_test); + tcase_add_test(tc, eina_range_equal_test); +} diff --git a/src/tests/eina/meson.build b/src/tests/eina/meson.build index b6ba688e8b..f755be4c2a 100644 --- a/src/tests/eina/meson.build +++ b/src/tests/eina/meson.build @@ -29,6 +29,7 @@ eina_test_src = files( 'eina_test_benchmark.c', 'eina_test_mempool.c', 'eina_test_rectangle.c', +'eina_test_range.c', 'eina_test_list.c', 'eina_test_matrixsparse.c', 'eina_test_tiler.c', From 97098dcc50b62e51dad3469619ed55242ca01a80 Mon Sep 17 00:00:00 2001 From: Yeongjong Lee Date: Thu, 23 Jan 2020 07:30:13 +0900 Subject: [PATCH 11/12] csharp: cleanup concrete class Summary: Concrete class is only used to call static member of NativeMethod. they don't need any inheritance and implementation of c functions. Depends on D9893 Test Plan: ninja test Reviewers: lauromoura, felipealmeida Subscribers: Jaehyun_Cho, woohyun, segfaultxavi, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9894 --- src/bin/eolian_mono/eolian/mono/events.hh | 2 +- src/bin/eolian_mono/eolian/mono/klass.hh | 108 +++--------------- .../eolian_mono/eolian/mono/name_helpers.hh | 17 ++- .../eolian/mono/struct_definition.hh | 3 +- .../mono/eina_mono/eina_container_common.cs | 24 ---- src/bindings/mono/eo_mono/iwrapper.cs | 12 +- src/tests/efl_mono/Eo.cs | 32 ++++++ src/tests/efl_mono/dummy_test_object.c | 22 ++++ src/tests/efl_mono/dummy_test_object.eo | 17 +++ 9 files changed, 106 insertions(+), 131 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh index 7405f8c2e1..b6cb4aa511 100644 --- a/src/bin/eolian_mono/eolian/mono/events.hh +++ b/src/bin/eolian_mono/eolian/mono/events.hh @@ -131,7 +131,7 @@ struct unpack_event_args_visitor } bool operator()(grammar::attributes::klass_name const& cls) const { - return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_concrete_name(cls) + ")").generate(sink, attributes::unused, *context); + return as_generator("(Efl.Eo.Globals.CreateWrapperFor(info) as " + name_helpers::klass_full_interface_name(cls) + ")").generate(sink, attributes::unused, *context); } bool operator()(attributes::complex_type_def const& types) const { diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index 072ea6c143..da6fd6d45c 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -193,98 +193,9 @@ struct klass auto concrete_cxt = context_add_tag(class_context{class_context::concrete, name_helpers::klass_full_concrete_or_interface_name(cls)}, context); - auto concrete_name = name_helpers::klass_concrete_name(cls); - auto interface_name = name_helpers::klass_interface_name(cls); - // We can't make these internal yet as they have methods that are used by - // other classes that implement the interface. - if(!as_generator - ( - documentation(1) - << scope_tab << "public sealed " << (is_partial ? "partial ":"") << "class " << concrete_name << " :\n" - << scope_tab(2) << (root ? "Efl.Eo.EoWrapper" : "") << (klass_full_concrete_or_interface_name % "") - << ",\n" << scope_tab(2) << interface_name - << *(",\n" << scope_tab(2) << name_helpers::klass_full_concrete_or_interface_name) << "\n" - << scope_tab << "{\n" - ).generate(sink, std::make_tuple(cls, inherit_classes, inherit_interfaces), concrete_cxt)) - return false; - - if (!generate_fields(sink, cls, concrete_cxt)) - return false; - - if (!as_generator - ( - scope_tab(2) << "/// Subclasses should override this constructor if they are expected to be instantiated from native code.\n" - << scope_tab(2) << "/// Do not call this constructor directly.\n" - << scope_tab(2) << "/// Tag struct storing the native handle of the object being constructed.\n" - << scope_tab(2) << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n" - << scope_tab(2) << "{\n" - << scope_tab(2) << "}\n\n" - ) - .generate(sink, attributes::unused, concrete_cxt)) - return false; - - if (!as_generator - ( - scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag(concrete_cxt).actual_library_name(cls.filename) - << ")] internal static extern System.IntPtr\n" - << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n\n" - << scope_tab(2) << "/// Initializes a new instance of the class.\n" - << scope_tab(2) << "/// Internal usage: This is used when interacting with C code and should not be used directly.\n" - << scope_tab(2) << "/// The native pointer to be wrapped.\n" - << scope_tab(2) << "private " << concrete_name << "(Efl.Eo.WrappingHandle wh) : base(wh)\n" - << scope_tab(2) << "{\n" - << scope_tab(2) << "}\n\n" - ) - .generate(sink, attributes::unused, concrete_cxt)) - return false; - - if (!generate_events(sink, cls, concrete_cxt)) - return false; - - if (!as_generator(lit("#pragma warning disable CS0628\n")).generate(sink, attributes::unused, concrete_cxt)) - return false; - - // Parts - if(!as_generator(*(part_definition)) - .generate(sink, cls.parts, concrete_cxt)) return false; - - // Concrete function definitions - auto implemented_methods = helpers::get_all_implementable_methods(cls, concrete_cxt); - if(!as_generator(*(function_definition)) - .generate(sink, implemented_methods, concrete_cxt)) return false; - - // Async wrappers - if(!as_generator(*(async_function_definition)).generate(sink, implemented_methods, concrete_cxt)) - return false; - - // Property wrappers - if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, cls.properties, concrete_cxt)) - return false; - - for (auto&& klass : helpers::non_implemented_interfaces(cls, concrete_cxt)) - { - attributes::klass_def c(get_klass(klass, cls.unit), cls.unit); - if (!as_generator(*(property_wrapper_definition(cls))).generate(sink, c.properties, concrete_cxt)) - return false; - } - - if (!as_generator(lit("#pragma warning restore CS0628\n")).generate(sink, attributes::unused, concrete_cxt)) - return false; - - // Copied from nativeinherit class, used when setting up providers. - if(!as_generator( - scope_tab(2) << "private static IntPtr GetEflClassStatic()\n" - << scope_tab(2) << "{\n" - << scope_tab(2) << scope_tab << "return " << name_helpers::klass_get_full_name(cls) << "();\n" - << scope_tab(2) << "}\n\n" - ).generate(sink, attributes::unused, concrete_cxt)) - return false; - - if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt))) + if(!generate_native_inherit_class(sink, cls, change_indentation(indent, concrete_cxt))) return true; - - if(!as_generator(scope_tab << "}\n").generate(sink, attributes::unused, concrete_cxt)) return false; } // Inheritable class @@ -427,6 +338,7 @@ struct klass auto inherit_name = name_helpers::klass_inherit_name(cls); auto implementable_methods = helpers::get_all_registerable_methods(cls, context); bool root = !helpers::has_regular_ancestor(cls); + bool is_concrete = context_find_tag(context).current_wrapper_kind == class_context::concrete; auto const& indent = current_indentation(inative_cxt).inc(); std::string klass_since; @@ -447,11 +359,23 @@ struct klass << klass_since << indent << "/// \n" << indent << "[EditorBrowsable(EditorBrowsableState.Never)]\n" - << indent << "internal new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n" + << indent << "internal " << (is_concrete ? "" : "new ") << "class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n" << indent << "{\n" ).generate(sink, attributes::unused, inative_cxt)) return false; + if(is_concrete) + { + if (!as_generator + ( + scope_tab(2) << "[System.Runtime.InteropServices.DllImport(" << context_find_tag(context).actual_library_name(cls.filename) + << ")] internal static extern System.IntPtr\n" + << scope_tab(2) << scope_tab << name_helpers::klass_get_name(cls) << "();\n" + ) + .generate(sink, attributes::unused, inative_cxt)) + return false; + } + if(implementable_methods.size() >= 1) { if(!as_generator( @@ -502,7 +426,7 @@ struct klass ).generate(sink, attributes::unused, inative_cxt)) return false; - if (!root || context_find_tag(context).current_wrapper_kind != class_context::concrete) + if (!root || !is_concrete) if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type, false));\n").generate(sink, attributes::unused, inative_cxt)) return false; diff --git a/src/bin/eolian_mono/eolian/mono/name_helpers.hh b/src/bin/eolian_mono/eolian/mono/name_helpers.hh index 7f71d9279b..ae958ba623 100644 --- a/src/bin/eolian_mono/eolian/mono/name_helpers.hh +++ b/src/bin/eolian_mono/eolian/mono/name_helpers.hh @@ -399,9 +399,7 @@ struct klass_full_interface_name_generator template inline std::string klass_concrete_name(T const& klass) { - return utils::remove_all(klass.eolian_name, '_') + ((klass.type == attributes::class_type::mixin - || klass.type == attributes::class_type::interface_) - ? "Concrete" : ""); + return utils::remove_all(klass.eolian_name, '_'); } template @@ -467,14 +465,19 @@ inline std::string klass_inherit_name(T const& klass) } template -inline std::string klass_native_inherit_name(EINA_UNUSED T const& klass) +inline std::string klass_native_inherit_name(T const& klass) { - return "NativeMethods"; + return ((klass.type == attributes::class_type::mixin + || klass.type == attributes::class_type::interface_) ? klass_interface_name(klass) : "") + "NativeMethods"; } template inline std::string klass_full_native_inherit_name(T const& klass) { + if(klass.type == attributes::class_type::mixin + || klass.type == attributes::class_type::interface_) + return join_namespaces(klass.namespaces, '.', managed_namespace) + klass_native_inherit_name(klass); + return klass_full_concrete_name(klass) + "." + klass_native_inherit_name(klass); } @@ -487,6 +490,10 @@ inline std::string klass_get_name(T const& clsname) template inline std::string klass_get_full_name(T const& clsname) { + if(clsname.type == attributes::class_type::mixin + || clsname.type == attributes::class_type::interface_) + return klass_get_name(clsname); + return klass_full_concrete_name(clsname) + "." + klass_get_name(clsname); } diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index 176b5518d7..1f4152aa74 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -190,11 +190,10 @@ struct to_external_field_convert_generator if (klass) { auto interface_name = name_helpers::klass_full_interface_name(*klass); - auto concrete_name = name_helpers::klass_full_concrete_name(*klass); if (!as_generator( "\n" << indent << scope_tab << scope_tab << "_external_struct." << string - << " = (" << concrete_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n" + << " = (" << interface_name << ") Efl.Eo.Globals.CreateWrapperFor(_internal_struct." << string << ");\n" ).generate(sink, std::make_tuple(field_name, field_name), context)) return false; } diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs index 192469a033..a07153e51a 100644 --- a/src/bindings/mono/eina_mono/eina_container_common.cs +++ b/src/bindings/mono/eina_mono/eina_container_common.cs @@ -1003,22 +1003,6 @@ internal static class TraitFunctions private static IDictionary register = new Dictionary(); - private static System.Type AsEflInstantiableType(System.Type type) - { - if (!IsEflObject(type)) - { - return null; - } - - if (type.IsInterface) - { - string fullName = type.FullName + "Concrete"; - return type.Assembly.GetType(fullName); // That was our best guess... - } - - return type; // Not interface, so it should be a concrete. - } - public static object RegisterTypeTraits() { Eina.Log.Debug($"Finding TypeTraits for {typeof(T).Name}"); @@ -1026,14 +1010,6 @@ internal static class TraitFunctions var type = typeof(T); if (IsEflObject(type)) { - System.Type concrete = AsEflInstantiableType(type); - if (concrete == null || !type.IsAssignableFrom(concrete)) - { - throw new Exception("Failed to get a suitable concrete class for this type."); - } - - // No need to pass concrete as the traits class will use reflection to get the actually most - // derived type returned. traits = new EflObjectElementTraits(); } else if (IsString(type)) diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs index 780735fcca..ceae250bc9 100644 --- a/src/bindings/mono/eo_mono/iwrapper.cs +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -1221,14 +1221,12 @@ internal static class ClassRegister if (objectType.IsInterface) { - // Try to get the *Concrete class - var assembly = objectType.Assembly; - objectType = assembly.GetType(objectType.FullName + "Concrete"); - - if (objectType == null) - { + // Try to get the *NativeMethods class + var nativeMethods = (Efl.Eo.NativeClass)System.Attribute.GetCustomAttributes(objectType)?.FirstOrDefault(attr => attr is Efl.Eo.NativeClass); + if (nativeMethods == null) return IntPtr.Zero; - } + + return nativeMethods.GetEflClass(); } var method = objectType.GetMethod("GetEflClassStatic", diff --git a/src/tests/efl_mono/Eo.cs b/src/tests/efl_mono/Eo.cs index 70e9d29c16..8d00155e10 100644 --- a/src/tests/efl_mono/Eo.cs +++ b/src/tests/efl_mono/Eo.cs @@ -385,6 +385,16 @@ class TestEoMultipleChildClasses class TestCsharpProperties { + + private class MyObject : Dummy.TestObject + { + public MyObject(Efl.Object parent = null) : base(parent) + { + } + private MyObject(ConstructingHandle ch) : base(ch) + { + } + } public static void test_csharp_properties() { var obj = new Dummy.TestObject(); @@ -428,6 +438,28 @@ class TestCsharpProperties iface.Dispose(); } + public static void test_iface_value_property() + { + var obj = new Dummy.TestObject(); + var prop = new MyObject(); + + obj.IfaceValueProp = prop; + Test.AssertEquals(obj.IfaceValueProp, prop); + + obj.Dispose(); + prop.Dispose(); + } + + public static void test_iface_value_from_c() + { + var obj = new Dummy.TestObject(); + + obj.SetIfaceKlassProp(typeof(MyObject)); + Test.AssertEquals(obj.IfaceValueFromC.GetType(), typeof(MyObject)); + + obj.Dispose(); + } + public static void test_csharp_multi_valued_prop() { var obj = new Dummy.TestObject(); diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c index b87aff1cd4..687737a4aa 100644 --- a/src/tests/efl_mono/dummy_test_object.c +++ b/src/tests/efl_mono/dummy_test_object.c @@ -38,6 +38,8 @@ typedef struct Dummy_Test_Object_Data int prop1; int prop2; Eo *hidden_object; + Dummy_Test_Iface *iface_value_prop; + Efl_Class *iface_klass; // Containers passed to C# as iterator/accessors Eina_Array *out_array; @@ -4784,6 +4786,26 @@ Eo *_dummy_test_object_hidden_object_get(EINA_UNUSED const Eo *obj, Dummy_Test_O return pd->hidden_object; } +Dummy_Test_Iface *_dummy_test_object_iface_value_prop_get(EINA_UNUSED const Eo *obj, Dummy_Test_Object_Data *pd) +{ + return pd->iface_value_prop; +} + +void _dummy_test_object_iface_value_prop_set(EINA_UNUSED Eo *obj, Dummy_Test_Object_Data *pd, Dummy_Test_Iface *prop) +{ + pd->iface_value_prop = prop; +} + +void _dummy_test_object_iface_klass_prop_set(EINA_UNUSED Eo *obj, Dummy_Test_Object_Data *pd, Efl_Class *klass) +{ + pd->iface_klass = klass; +} + +Dummy_Test_Iface *_dummy_test_object_iface_value_from_c_get(const Eo *obj, Dummy_Test_Object_Data *pd) +{ + return efl_add(pd->iface_klass, (Eo*)obj); +} + // Inherit int _dummy_inherit_helper_receive_dummy_and_call_int_out(Dummy_Test_Object *x) { diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo index cf2ae7ce03..ee24e5ef9b 100644 --- a/src/tests/efl_mono/dummy_test_object.eo +++ b/src/tests/efl_mono/dummy_test_object.eo @@ -1664,6 +1664,23 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { obj: Efl.Object; } } + @property iface_value_prop { + values { + prop: Dummy.Test_Iface; + } + } + @property iface_klass_prop { + set {} + values { + klass: Efl.Class; + } + } + @property iface_value_from_c { + get {} + values { + prop: Dummy.Test_Iface; + } + } } implements { Efl.Object.constructor; From 68d7f584cb78402dbe884d3a7b902c4735d96f8a Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Wed, 22 Jan 2020 23:31:30 +0000 Subject: [PATCH 12/12] edje - store original size in edje struct and dont exceed max size evas can tell us max texture size. in edje when we have image sets (multiple images that make up mipmaps effectively for a logical image), we now can avoid choosing an image that exceeds max texture size. this actually fixes bugs i have seen on the rpi3 which has a max texture size of 2048 which makes it easy to exceed it with wallpapers or even terminology's default theme. so combo of new feature and fix... but requires a rebuild of the edj files... @feat + @fix --- src/lib/edje/edje_calc.c | 9 ++++++++- src/lib/edje/edje_data.c | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index 336bbc00cc..07f25ec02d 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -552,7 +552,7 @@ _edje_image_find(Evas_Object *obj, Edje *ed, Edje_Real_Part_Set **eps, Edje_Image_Directory_Set_Entry *entry; Edje_Image_Directory_Set *set = NULL; Eina_List *l; - int w = 0, h = 0, id; + int w = 0, h = 0, id, maxw = 0, maxh = 0; if (!st && !imid) return -1; if (st && !st->image.set) return st->image.id; @@ -581,8 +581,15 @@ _edje_image_find(Evas_Object *obj, Edje *ed, Edje_Real_Part_Set **eps, if (!set) set = ed->file->image_dir->sets + id; + if (set->entries) + evas_image_max_size_get(evas_object_evas_get(obj), &maxw, &maxh); EINA_LIST_FOREACH(set->entries, l, entry) { + // skip images that exceed max size + if ((maxw > 0) && (maxh > 0) && + (entry->size.w > 0) && (entry->size.h > 0) && + ((w > entry->size.w) || (h > entry->size.h))) + continue; if ((entry->size.min.w <= w) && (w <= entry->size.max.w)) { if ((entry->size.min.h <= h) && (h <= entry->size.max.h)) diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index ca9cbf11ad..daa4a01ac7 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -399,6 +399,8 @@ _edje_edd_init(void) eet_data_descriptor_file_new(&eddc); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "name", name, EET_T_STRING); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "id", id, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "w", size.w, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "h", size.h, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "min.w", size.min.w, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "min.h", size.min.h, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_image_directory_set_entry, Edje_Image_Directory_Set_Entry, "max.w", size.max.w, EET_T_INT);