From 4ff8c5f7b25ee539c930e5aaa6352cc0304d3908 Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 26 Jun 2019 20:48:19 +0900 Subject: [PATCH 01/36] efl_canvas_vg_container: remove unnecessary parent set. the duplicated object must be set its parent by caller, it shouldn't set it by itself internally. --- src/lib/evas/canvas/efl_canvas_vg_container.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c index 4d11e0b5cb..2daa65fb80 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_container.c +++ b/src/lib/evas/canvas/efl_canvas_vg_container.c @@ -399,7 +399,6 @@ _efl_canvas_vg_container_efl_duplicate_duplicate(const Eo *obj, container = efl_duplicate(efl_super(obj, MY_CLASS)); efl_event_callback_add(container, EFL_EVENT_INVALIDATE, _invalidate_cb, NULL); - efl_parent_set(container, efl_parent_get(obj)); //Copy Mask if (pd->mask_src) From 5b00dc344febd4004f268d8d76a05f7579d08288 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Wed, 26 Jun 2019 13:54:12 +0200 Subject: [PATCH 02/36] eolian: allow value types in view containers (iterators etc.) This restricts disallowing value types to containers that can own them. It also disallows usage of @owned on those view-only containers, as that makes no sense. --- src/lib/eolian/database_validate.c | 2 +- src/lib/eolian/eo_parser.c | 6 ++++-- src/tests/eolian/data/owning.eo | 4 +--- src/tests/eolian/data/owning_ref.c | 21 +++++---------------- 4 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/lib/eolian/database_validate.c b/src/lib/eolian/database_validate.c index 8deea6d595..c7254ed220 100644 --- a/src/lib/eolian/database_validate.c +++ b/src/lib/eolian/database_validate.c @@ -273,7 +273,7 @@ _validate_type(Validate_State *vals, Eolian_Type *tp) { if (!_validate_type(vals, itp)) return EINA_FALSE; - if ((kwid >= KW_accessor) && (kwid <= KW_list) && (kwid != KW_future)) + if (kwid == KW_array || kwid == KW_hash || kwid == KW_list) { if (!database_type_is_ownable(src, itp, EINA_TRUE)) { diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index f33db75f67..6b5d920409 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -768,8 +768,10 @@ parse_type_void(Eo_Lexer *ls, Eina_Bool allow_ptr) def->base_type = eo_lexer_type_release(ls, parse_type_void(ls, EINA_TRUE)); else def->base_type = eo_lexer_type_release(ls, parse_type(ls, EINA_TRUE)); - if ((def->base_type->owned = (ls->t.kw == KW_at_owned))) - eo_lexer_get(ls); + /* view-only types are not allowed to own the contents */ + if (tpid == KW_array || tpid == KW_hash || tpid == KW_list || tpid == KW_future) + if ((def->base_type->owned = (ls->t.kw == KW_at_owned))) + eo_lexer_get(ls); if (tpid == KW_hash) { check_next(ls, ','); diff --git a/src/tests/eolian/data/owning.eo b/src/tests/eolian/data/owning.eo index f74d683b78..ae926a5e35 100644 --- a/src/tests/eolian/data/owning.eo +++ b/src/tests/eolian/data/owning.eo @@ -15,9 +15,7 @@ class Owning { test2 { params { test1 : list @owned; - test2 : iterator @owned; - test3 : hash @owned; - test4 : accessor @owned; + test2 : hash @owned; } } diff --git a/src/tests/eolian/data/owning_ref.c b/src/tests/eolian/data/owning_ref.c index 3df14c9098..10a7f10a13 100644 --- a/src/tests/eolian/data/owning_ref.c +++ b/src/tests/eolian/data/owning_ref.c @@ -13,32 +13,21 @@ _owning_test1_ownership_fallback(Eina_List *test1, Eina_Iterator *test2, Eina_Ha EOAPI EFL_VOID_FUNC_BODYV_FALLBACK(owning_test1, _owning_test1_ownership_fallback(test1, test2, test3, test4);, EFL_FUNC_CALL(test1, test2, test3, test4), Eina_List *test1, Eina_Iterator *test2, Eina_Hash *test3, Eina_Accessor *test4); -void _owning_test2(Eo *obj, Owning_Data *pd, Eina_List *test1, Eina_Iterator *test2, Eina_Hash *test3, Eina_Accessor *test4); +void _owning_test2(Eo *obj, Owning_Data *pd, Eina_List *test1, Eina_Hash *test2); static void -_owning_test2_ownership_fallback(Eina_List *test1, Eina_Iterator *test2, Eina_Hash *test3, Eina_Accessor *test4) +_owning_test2_ownership_fallback(Eina_List *test1, Eina_Hash *test2) { Test_A *test1_iter; EINA_LIST_FREE(test1,test1_iter) { free_a(test1_iter); } - Test_A *test2_iter; - EINA_ITERATOR_FOREACH(test2,test2_iter) - { - free_a(test2_iter); - } - eina_hash_free_cb_set(test3,NULL); - eina_hash_free(test3); - Test_A *test4_iter; - unsigned int test4_i = 0; - EINA_ACCESSOR_FOREACH(test4,test4_i,test4_iter) - { - free_a(test4_iter); - } + eina_hash_free_cb_set(test2,NULL); + eina_hash_free(test2); } -EOAPI EFL_VOID_FUNC_BODYV_FALLBACK(owning_test2, _owning_test2_ownership_fallback(test1, test2, test3, test4);, EFL_FUNC_CALL(test1, test2, test3, test4), Eina_List *test1, Eina_Iterator *test2, Eina_Hash *test3, Eina_Accessor *test4); +EOAPI EFL_VOID_FUNC_BODYV_FALLBACK(owning_test2, _owning_test2_ownership_fallback(test1, test2);, EFL_FUNC_CALL(test1, test2), Eina_List *test1, Eina_Hash *test2); static Eina_Bool _owning_class_initializer(Efl_Class *klass) From f085bd8ae7500d7c9b961cea713d0e9da25afb1f Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Jun 2019 08:50:53 -0400 Subject: [PATCH 03/36] efl_input_interface: add test to verify focus in/out Summary: this verifies that EFL_EVENT_FOCUS_IN / EFL_EVENT_FOCUS_OUT are emitted and passed with the correct event types, and fields on the event object. Reviewers: zmike, segfaultxavi Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9166 --- src/tests/elementary/efl_ui_test_win.c | 34 ++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index 1482f14867..a0cc374969 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -94,9 +94,43 @@ EFL_START_TEST(efl_ui_win_test_object_focus) } EFL_END_TEST +static void +create_environment(Eo **win, Eo **rect) +{ + *win = efl_new(EFL_UI_WIN_CLASS); + *rect = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(*win)); + efl_canvas_object_seat_focus_add(*rect, NULL); +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_focus) +{ + Efl_Ui_Win *win; + Efl_Canvas_Object *rect, *focus_in = NULL, *focus_out = NULL; + create_environment(&win, &rect); + efl_canvas_object_seat_focus_del(rect, NULL); + + efl_event_callback_add(rect, EFL_EVENT_FOCUS_IN , _check_focus_event, &focus_in); + efl_event_callback_add(rect, EFL_EVENT_FOCUS_OUT, _check_focus_event, &focus_out); + + efl_canvas_object_seat_focus_add(rect, NULL); + ck_assert_ptr_eq(focus_out, NULL); + ck_assert_ptr_eq(focus_in, rect); + focus_out = NULL; + focus_in = NULL; + + efl_canvas_object_seat_focus_del(rect, NULL); + ck_assert_ptr_eq(focus_out, rect); + ck_assert_ptr_eq(focus_in, NULL); + focus_out = NULL; + focus_in = NULL; +} +EFL_END_TEST + void efl_ui_test_win(TCase *tc) { tcase_add_test(tc, efl_ui_win_test_scene_focus); tcase_add_test(tc, efl_ui_win_test_object_focus); + tcase_add_test(tc, efl_ui_win_test_object_focus); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_focus); } From ea0784d3186b01039749ae12faa01244ba2fea92 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Jun 2019 08:50:59 -0400 Subject: [PATCH 04/36] evas_events: fix setting of 'pressed' member in Efl_Input_Key_Data Summary: this also adds tests verifying that EFL_EVENT_KEY_DOWN / EFL_EVENT_KEY_UP are emitted and passed with the correct event types, and fields on the event object. Depends on D9166 Reviewers: zmike, segfaultxavi Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9167 --- src/lib/evas/canvas/evas_events.c | 2 ++ src/tests/elementary/efl_ui_test_win.c | 35 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c index 8ab6bf4cd4..9d40007709 100644 --- a/src/lib/evas/canvas/evas_events.c +++ b/src/lib/evas/canvas/evas_events.c @@ -3462,9 +3462,11 @@ _canvas_event_feed_key_legacy(Eo *eo_e, Evas_Public_Data *e, ev->compose = compose; ev->timestamp = timestamp; ev->keycode = keycode; + ev->pressed = down; ev->no_stringshare = EINA_TRUE; ev->device = efl_ref(_evas_event_legacy_device_get(e->evas, EINA_FALSE)); + if (down) _canvas_event_feed_key_down_internal(e, ev); else diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index a0cc374969..67df0b21b5 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -126,6 +126,40 @@ EFL_START_TEST(efl_ui_win_test_efl_input_interface_focus) } EFL_END_TEST +#define TIMESTAMP 1337 + +static void +_check_key_event(void *data, const Efl_Event *ev) +{ + Eina_Bool *pressed = data; + + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_str_eq(efl_input_key_name_get(ev->info), "odiaeresis"); + ck_assert_str_eq(efl_input_key_get(ev->info), "ö"); + ck_assert_str_eq(efl_input_key_string_get(ev->info), "Ö"); + ck_assert_str_eq(efl_input_key_compose_string_get(ev->info), "Ö"); + ck_assert_int_eq(efl_input_key_code_get(ev->info), 0xffe1); + *pressed = efl_input_key_pressed_get(ev->info); +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_key_down) +{ + Efl_Ui_Win *win; + Eina_Bool pressed = EINA_FALSE; + Efl_Canvas_Object *rect; + create_environment(&win, &rect); + + efl_event_callback_add(rect, EFL_EVENT_KEY_DOWN , _check_key_event, &pressed); + efl_event_callback_add(rect, EFL_EVENT_KEY_UP, _check_key_event, &pressed); + + evas_event_feed_key_down_with_keycode(evas_object_evas_get(win), "odiaeresis", "ö", "Ö", "Ö", TIMESTAMP, NULL, 0xffe1); + ck_assert_int_eq(pressed, EINA_TRUE); + + evas_event_feed_key_up_with_keycode(evas_object_evas_get(win), "odiaeresis", "ö", "Ö", "Ö", TIMESTAMP, NULL, 0xffe1); + ck_assert_int_eq(pressed, EINA_FALSE); +} +EFL_END_TEST + void efl_ui_test_win(TCase *tc) { @@ -133,4 +167,5 @@ efl_ui_test_win(TCase *tc) tcase_add_test(tc, efl_ui_win_test_object_focus); tcase_add_test(tc, efl_ui_win_test_object_focus); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_focus); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_key_down); } From b0455490e7a03def1fe2a0245250635f8de96a52 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Jun 2019 08:51:06 -0400 Subject: [PATCH 05/36] efl_input_interface: test pointer move down up Summary: this verifies that EFL_EVENT_POINTER_MOVE / EFL_EVENT_POINTER_DOWN / EFL_EVENT_POINTER_UP are emitted and passed with the correct event types, and fields on the event object. Depends on D9167 Reviewers: zmike, segfaultxavi Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9168 --- src/tests/elementary/efl_ui_test_win.c | 117 +++++++++++++++++++++++++ 1 file changed, 117 insertions(+) diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index 67df0b21b5..fb4728222f 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -94,12 +94,24 @@ EFL_START_TEST(efl_ui_win_test_object_focus) } EFL_END_TEST + +static void +prepare_window_norendered(void *data EINA_UNUSED, Evas *e, void *event_info EINA_UNUSED) +{ + efl_task_end(efl_app_main_get()); + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, prepare_window_norendered); +} + static void create_environment(Eo **win, Eo **rect) { *win = efl_new(EFL_UI_WIN_CLASS); *rect = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(*win)); efl_canvas_object_seat_focus_add(*rect, NULL); + efl_gfx_entity_geometry_set(*win, EINA_RECT(0, 0, 200, 200)); + efl_gfx_entity_geometry_set(*rect, EINA_RECT(0, 0, 200, 200)); + evas_event_callback_add(evas_object_evas_get(*win), EVAS_CALLBACK_RENDER_POST, prepare_window_norendered, NULL); + efl_loop_begin(efl_main_loop_get()); } EFL_START_TEST(efl_ui_win_test_efl_input_interface_focus) @@ -160,6 +172,108 @@ EFL_START_TEST(efl_ui_win_test_efl_input_interface_key_down) } EFL_END_TEST +static void +position_eq(Eina_Position2D a, Eina_Position2D b) +{ + ck_assert_int_eq(a.x, b.x); + ck_assert_int_eq(a.y, b.y); +} + +static void +_check_ptr_move_event(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_previous_position_get(ev->info), EINA_POSITION2D(20, 20)); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(25, 25)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_MOVE); + *called = EINA_TRUE; +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_move) +{ + Efl_Ui_Win *win; + Eina_Bool called = EINA_FALSE; + Efl_Canvas_Object *rect; + create_environment(&win, &rect); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 20, 20, TIMESTAMP - 1, NULL); + efl_event_callback_add(rect, EFL_EVENT_POINTER_MOVE , _check_ptr_move_event, &called); + evas_event_feed_mouse_move(evas_object_evas_get(win), 25, 25, TIMESTAMP, NULL); + ck_assert_int_eq(called, EINA_TRUE); +} +EFL_END_TEST + +static void +_check_ptr_down_event(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), EINA_TRUE); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), EVAS_BUTTON_TRIPLE_CLICK); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 1); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_DOWN); + *called = EINA_TRUE; +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_down) +{ + Efl_Ui_Win *win; + Eina_Bool called = EINA_FALSE; + Efl_Canvas_Object *rect; + create_environment(&win, &rect); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 20, 20, TIMESTAMP - 1, NULL); + efl_event_callback_add(rect, EFL_EVENT_POINTER_DOWN , _check_ptr_down_event, &called); + evas_event_feed_mouse_down(evas_object_evas_get(win), 1, EVAS_BUTTON_TRIPLE_CLICK, TIMESTAMP, NULL); + ck_assert_int_eq(called, EINA_TRUE); +} +EFL_END_TEST + +static void +_check_ptr_up_event(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), EINA_TRUE); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), EVAS_BUTTON_TRIPLE_CLICK); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 1); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_UP); + *called = EINA_TRUE; +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_up) +{ + Efl_Ui_Win *win; + Eina_Bool called = EINA_FALSE; + Efl_Canvas_Object *rect; + create_environment(&win, &rect); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 20, 20, TIMESTAMP - 1, NULL); + evas_event_feed_mouse_down(evas_object_evas_get(win), 1, EVAS_BUTTON_TRIPLE_CLICK, TIMESTAMP, NULL); + efl_event_callback_add(rect, EFL_EVENT_POINTER_UP , _check_ptr_up_event, &called); + evas_event_feed_mouse_up(evas_object_evas_get(win), 1, EVAS_BUTTON_TRIPLE_CLICK, TIMESTAMP, NULL); + ck_assert_int_eq(called, EINA_TRUE); +} +EFL_END_TEST + void efl_ui_test_win(TCase *tc) { @@ -168,4 +282,7 @@ efl_ui_test_win(TCase *tc) tcase_add_test(tc, efl_ui_win_test_object_focus); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_focus); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_key_down); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_move); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_down); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_up); } From 132d3dfb92dea3fcd2fde947b9b41a614be7b24f Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Jun 2019 08:51:11 -0400 Subject: [PATCH 06/36] efl_input_interface: test pointer in and out events on a object Summary: this verifies that EFL_EVENT_POINTER_IN EFL_EVENT_POINTER_OUT are emitted correctly with the correct event content. Depends on D9168 Reviewers: zmike, segfaultxavi Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9169 --- src/tests/elementary/efl_ui_test_win.c | 61 ++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index fb4728222f..2f362467cd 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -274,6 +274,66 @@ EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_up) } EFL_END_TEST +static void +_check_pointer_in_cb(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_IN ); + *called = EINA_TRUE; +} + +static void +_check_pointer_out_cb(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(5, 5)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_OUT ); + *called = EINA_TRUE; +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_in_out) +{ + Efl_Ui_Win *win; + Eina_Bool pointer_in = EINA_FALSE, pointer_out = EINA_FALSE; + Efl_Canvas_Object *rect; + + create_environment(&win, &rect); + evas_event_feed_mouse_move(evas_object_evas_get(win), 5, 5, TIMESTAMP - 1, NULL); + evas_object_geometry_set(rect, 10, 10, 20, 20); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 5, 5, TIMESTAMP - 1, NULL); + efl_event_callback_add(rect, EFL_EVENT_POINTER_IN, _check_pointer_in_cb, &pointer_in); + efl_event_callback_add(rect, EFL_EVENT_POINTER_OUT, _check_pointer_out_cb, &pointer_out); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 20, 20, TIMESTAMP, NULL); + ck_assert_int_eq(pointer_in, EINA_TRUE); + ck_assert_int_eq(pointer_out, EINA_FALSE); + pointer_in = EINA_FALSE; + pointer_out = EINA_FALSE; + + evas_event_feed_mouse_move(evas_object_evas_get(win), 5, 5, TIMESTAMP, NULL); + ck_assert_int_eq(pointer_in, EINA_FALSE); + ck_assert_int_eq(pointer_out, EINA_TRUE); +} +EFL_END_TEST + void efl_ui_test_win(TCase *tc) { @@ -285,4 +345,5 @@ efl_ui_test_win(TCase *tc) tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_move); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_down); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_up); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_in_out); } From 4fe13887cab6c42154f3a5d846f5c01c7e3df5d7 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Jun 2019 08:51:16 -0400 Subject: [PATCH 07/36] efl_input_interface: add tests for mouse wheel emitting Summary: this tests if z and direction is correctly emitted Depends on D9169 Reviewers: zmike, segfaultxavi Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9170 --- src/tests/elementary/efl_ui_test_win.c | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index 2f362467cd..cfc57a7834 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -334,6 +334,38 @@ EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_in_out) } EFL_END_TEST +static void +_check_pointer_wheel_cb(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 2); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 1); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_WHEEL ); + *called = EINA_TRUE; +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_wheel) +{ + Efl_Ui_Win *win; + Eina_Bool pointer_wheel = EINA_FALSE; + Efl_Canvas_Object *rect; + + create_environment(&win, &rect); + + efl_event_callback_add(rect, EFL_EVENT_POINTER_WHEEL, _check_pointer_wheel_cb, &pointer_wheel); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 20, 20, TIMESTAMP, NULL); + evas_event_feed_mouse_wheel(evas_object_evas_get(win), 1, 2, TIMESTAMP, NULL); + ck_assert_int_eq(pointer_wheel, EINA_TRUE); +} +EFL_END_TEST void efl_ui_test_win(TCase *tc) { @@ -346,4 +378,5 @@ efl_ui_test_win(TCase *tc) tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_down); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_up); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_in_out); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_wheel); } From 03077e238e8a38b0811601a396b99c01a581281e Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Wed, 26 Jun 2019 09:54:45 -0400 Subject: [PATCH 08/36] efl_ui_suite: remove duplicated code Summary: there is a helper for this function, lets use it. Depends on D9181 Reviewers: stefan_schmidt, segfaultxavi, zmike, Jaehyun_Cho Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9182 --- .../elementary/efl_ui_test_active_view.c | 21 ++----------------- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/src/tests/elementary/efl_ui_test_active_view.c b/src/tests/elementary/efl_ui_test_active_view.c index c471b4b7c6..44c5250bb5 100644 --- a/src/tests/elementary/efl_ui_test_active_view.c +++ b/src/tests/elementary/efl_ui_test_active_view.c @@ -5,14 +5,13 @@ #include #include "efl_ui_suite.h" #include "eo_internal.h" +#include "suite_helpers.h" EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_view_manager, "efl_ui_active_view_view_manager", EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_CLASS); EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_indicator, "efl_ui_active_view_indicator", EFL_UI_ACTIVE_VIEW_INDICATOR_CLASS); static Efl_Ui_Win *win; static Efl_Ui_Active_View_Container *container; -static int tree_abort; -static int tree_abort_level; typedef struct { struct { @@ -608,22 +607,6 @@ EFL_START_TEST (efl_ui_active_view_test_pop3) } EFL_END_TEST -static void -_shutdown(void) -{ - eina_log_abort_on_critical_set(tree_abort); - eina_log_abort_on_critical_level_set(tree_abort_level); -} - -static void -_setup(void) -{ - tree_abort = eina_log_abort_on_critical_get(); - tree_abort_level = eina_log_abort_on_critical_level_get(); - eina_log_abort_on_critical_level_set(2); - eina_log_abort_on_critical_set(1); -} - static void active_view_setup() { @@ -645,7 +628,7 @@ active_view_teardown() void efl_ui_test_active_view(TCase *tc) { - tcase_add_checked_fixture(tc, _setup, _shutdown); + tcase_add_checked_fixture(tc, fail_on_errors_setup, fail_on_errors_teardown); tcase_add_checked_fixture(tc, active_view_setup, active_view_teardown); tcase_add_test(tc, efl_ui_active_view_init); tcase_add_test(tc, efl_ui_active_view_active_index); From 9247b5aac37a81a7a66e36ecfcf83db8131d4620 Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Wed, 26 Jun 2019 09:53:13 -0400 Subject: [PATCH 09/36] ecore-wl2: Add missing @since for ecore_wl2_offer_mimes_get function ref T8014 --- src/lib/ecore_wl2/Ecore_Wl2.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index 4993afe9f4..b1b5f5a329 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -1765,6 +1765,7 @@ EAPI Ecore_Wl2_Drag_Action ecore_wl2_offer_action_get(Ecore_Wl2_Offer *offer); * @return a eina array of strdup´ed strings, this array must NOT be changed or freed * * @ingroup Ecore_Wl2_Dnd_Group + * @since 1.19 */ EAPI Eina_Array* ecore_wl2_offer_mimes_get(Ecore_Wl2_Offer *offer); From e962e6be4f91ea78faed1fb7335f68485bd7f1a3 Mon Sep 17 00:00:00 2001 From: Christopher Michael Date: Wed, 26 Jun 2019 10:00:00 -0400 Subject: [PATCH 10/36] ecore-wl2: Add missing doxygen for ecore_wl2_window_resizing_get function ref T8014 --- src/lib/ecore_wl2/Ecore_Wl2.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib/ecore_wl2/Ecore_Wl2.h b/src/lib/ecore_wl2/Ecore_Wl2.h index b1b5f5a329..59aee96eab 100644 --- a/src/lib/ecore_wl2/Ecore_Wl2.h +++ b/src/lib/ecore_wl2/Ecore_Wl2.h @@ -1943,6 +1943,16 @@ EAPI void ecore_wl2_window_buffer_attach(Ecore_Wl2_Window *win, void *buffer, in */ EAPI void ecore_wl2_display_flush(Ecore_Wl2_Display *display); +/** + * Get if a given window is resizing + * + * @param window + * + * @return EINA_TRUE if resizing, EINA_FALSE otherwise + * + * @ingroup Ecore_Wl2_Window_Group + * @since 1.21 + */ EAPI Eina_Bool ecore_wl2_window_resizing_get(Ecore_Wl2_Window *window); /** From 0e65d0c6514935640ddc657c29ac57b41628a9c6 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 26 Jun 2019 09:55:41 -0400 Subject: [PATCH 11/36] efl_ui: remove nstate widget Summary: this doesn't seem to serve a purpose anymore and there's no point in keeping it in tree fix T7866 Reviewers: woohyun, Jaehyun_Cho Reviewed By: Jaehyun_Cho Subscribers: cedric, #reviewers, #committers Tags: #efl_widgets Maniphest Tasks: T7866 Differential Revision: https://phab.enlightenment.org/D9176 --- data/elementary/themes/default.edc | 1 - data/elementary/themes/edc/efl/nstate.edc | 10 -- src/bin/elementary/meson.build | 1 - src/bin/elementary/test.c | 2 - src/bin/elementary/test_nstate.c | 34 ---- src/bin/elementary/test_part_bg.c | 7 +- src/bin/elementary/test_ui_active_view.c | 6 +- src/bin/elementary/test_ui_panel.c | 2 +- .../elementary/radio_cxx_example_01.cc | 8 +- src/lib/elementary/Efl_Ui.h | 1 - src/lib/elementary/Elementary.h | 1 - src/lib/elementary/efl_ui_check.c | 1 - src/lib/elementary/efl_ui_nstate.c | 155 ------------------ src/lib/elementary/efl_ui_nstate.eo | 39 ----- src/lib/elementary/efl_ui_nstate.h | 24 --- src/lib/elementary/efl_ui_nstate_private.h | 57 ------- src/lib/elementary/elm_dayselector.c | 2 +- src/lib/elementary/meson.build | 4 - 18 files changed, 12 insertions(+), 343 deletions(-) delete mode 100644 data/elementary/themes/edc/efl/nstate.edc delete mode 100644 src/bin/elementary/test_nstate.c delete mode 100644 src/lib/elementary/efl_ui_nstate.c delete mode 100644 src/lib/elementary/efl_ui_nstate.eo delete mode 100644 src/lib/elementary/efl_ui_nstate.h delete mode 100644 src/lib/elementary/efl_ui_nstate_private.h diff --git a/data/elementary/themes/default.edc b/data/elementary/themes/default.edc index 7e068d6dd9..201ccc9d2b 100644 --- a/data/elementary/themes/default.edc +++ b/data/elementary/themes/default.edc @@ -173,7 +173,6 @@ collections { #include "edc/efl/calendar.edc" #include "edc/efl/navigation_bar.edc" #include "edc/efl/navigation_layout.edc" -#include "edc/efl/nstate.edc" // XXX: mobile mode needs invisible scrollers... make signals that do this #include "edc/efl/scroller.edc" #include "edc/efl/list.edc" diff --git a/data/elementary/themes/edc/efl/nstate.edc b/data/elementary/themes/edc/efl/nstate.edc deleted file mode 100644 index 1d7a724411..0000000000 --- a/data/elementary/themes/edc/efl/nstate.edc +++ /dev/null @@ -1,10 +0,0 @@ -group { "efl/nstate"; - inherit: "efl/button"; - programs { - program { - signal: "mouse,clicked,1"; source: "event"; - action: SIGNAL_EMIT "efl,action,state,changed" "efl"; - } - } -} - diff --git a/src/bin/elementary/meson.build b/src/bin/elementary/meson.build index c17a182b86..8783cb3086 100644 --- a/src/bin/elementary/meson.build +++ b/src/bin/elementary/meson.build @@ -94,7 +94,6 @@ elementary_test_src = [ 'test_naviframe.c', 'test_naviframe_complex.c', 'test_notify.c', - 'test_nstate.c', 'test_panel.c', 'test_panes.c', 'test_ui_panes.c', diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index 31e8528b4c..1ea5799543 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -55,7 +55,6 @@ void test_clock_pause(void *data, Evas_Object *obj, void *event_info); void test_combobox(void *data, Evas_Object *obj, void *event_info); void test_check(void *data, Evas_Object *obj, void *event_info); void test_check_toggle(void *data, Evas_Object *obj, void *event_info); -void test_nstate(void *data, Evas_Object *obj, void *event_info); void test_radio(void *data, Evas_Object *obj, void *event_info); void test_layout(void *data, Evas_Object *obj, void *event_info); void test_layout2(void *data, Evas_Object *obj, void *event_info); @@ -1109,7 +1108,6 @@ add_tests: ADD_TEST(NULL, "Range Values", "Progressbar", test_progressbar); ADD_TEST(NULL, "Range Values", "Progressbar 2", test_progressbar2); ADD_TEST_EO(NULL, "Range Values", "Efl.Ui.Progressbar", test_ui_progressbar); - ADD_TEST_EO(NULL, "Range Values", "Efl.Ui.Nstate", test_nstate); ADD_TEST_EO(NULL, "Range Values", "Efl.Ui.Slider", test_ui_slider); ADD_TEST_EO(NULL, "Range Values", "Efl.Ui.Slider_Interval", test_slider_interval); diff --git a/src/bin/elementary/test_nstate.c b/src/bin/elementary/test_nstate.c deleted file mode 100644 index 717828eb40..0000000000 --- a/src/bin/elementary/test_nstate.c +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "elementary_config.h" -#endif -#include -#include - -static void -_state_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev) -{ - int val = efl_ui_nstate_value_get(ev->object); - efl_text_set(ev->object, eina_slstr_printf("nstate = %d", val)); -} - -void -test_nstate(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - Evas_Object *win, *bx, *nstate; - - win = efl_add_ref(EFL_UI_WIN_CLASS, NULL, - efl_text_set(efl_added, "N-state widget"), - elm_win_autodel_set(efl_added, EINA_TRUE)); - - bx = efl_add(EFL_UI_BOX_CLASS, win); - efl_content_set(win, bx); - - nstate = efl_add(EFL_UI_NSTATE_CLASS, win); - efl_event_callback_add(nstate, EFL_UI_NSTATE_EVENT_CHANGED, - _state_changed_cb, NULL); - efl_ui_nstate_count_set(nstate, 5); - efl_text_set(nstate, "nstate = 0"); - efl_pack(bx, nstate); - - efl_gfx_entity_size_set(win, EINA_SIZE2D(120, 80)); -} diff --git a/src/bin/elementary/test_part_bg.c b/src/bin/elementary/test_part_bg.c index d297d2ae74..cc01014c04 100644 --- a/src/bin/elementary/test_part_bg.c +++ b/src/bin/elementary/test_part_bg.c @@ -4,7 +4,7 @@ #include #include -#define MAX_NUM_OF_CONTENT 18 +#define MAX_NUM_OF_CONTENT 17 const Efl_Class *content_class[MAX_NUM_OF_CONTENT]; @@ -143,9 +143,8 @@ test_part_background(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void content_class[12] = EFL_UI_BG_CLASS; content_class[13] = EFL_UI_IMAGE_CLASS; content_class[14] = EFL_UI_IMAGE_ZOOMABLE_CLASS; - content_class[15] = EFL_UI_NSTATE_CLASS; - content_class[16] = EFL_UI_SPIN_CLASS; - content_class[17] = EFL_UI_SPIN_BUTTON_CLASS; + content_class[15] = EFL_UI_SPIN_CLASS; + content_class[16] = EFL_UI_SPIN_BUTTON_CLASS; win = efl_add_ref(EFL_UI_WIN_CLASS, NULL, efl_text_set(efl_added, "Widget Part Background"), diff --git a/src/bin/elementary/test_ui_active_view.c b/src/bin/elementary/test_ui_active_view.c index 38a79ea831..62ae450fa9 100644 --- a/src/bin/elementary/test_ui_active_view.c +++ b/src/bin/elementary/test_ui_active_view.c @@ -456,7 +456,7 @@ _animation_cb(void *data, const Efl_Event *ev) { Params *params = data; - efl_ui_active_view_view_manager_animation_enabled_set(efl_ui_active_view_manager_get(params->active_view), efl_ui_nstate_value_get(ev->object)); + efl_ui_active_view_view_manager_animation_enabled_set(efl_ui_active_view_manager_get(params->active_view), efl_ui_check_selected_get(ev->object)); } static void @@ -478,8 +478,8 @@ view_animation_cb(void *data, efl_added, NULL)); ck = efl_add(EFL_UI_CHECK_CLASS, box); - efl_event_callback_add(ck, EFL_UI_NSTATE_EVENT_CHANGED, _animation_cb, params); - efl_ui_nstate_value_set(ck, efl_ui_active_view_view_manager_animation_enabled_get(efl_ui_active_view_manager_get(params->active_view))); + efl_event_callback_add(ck, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _animation_cb, params); + efl_ui_check_selected_set(ck, efl_ui_active_view_view_manager_animation_enabled_get(efl_ui_active_view_manager_get(params->active_view))); efl_text_set(ck, "Animation"); efl_pack_end(box, ck); efl_gfx_entity_visible_set(ck, 1); diff --git a/src/bin/elementary/test_ui_panel.c b/src/bin/elementary/test_ui_panel.c index 91adb22301..22bd1a6ad4 100644 --- a/src/bin/elementary/test_ui_panel.c +++ b/src/bin/elementary/test_ui_panel.c @@ -114,7 +114,7 @@ test_ui_panel2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event check = efl_add(EFL_UI_CHECK_CLASS, box); efl_ui_check_selected_set(check, elm_config_scroll_thumbscroll_enabled_get()); efl_text_set(check, "Enable thumb scroll (temporarily"); - efl_event_callback_add(check, EFL_UI_NSTATE_EVENT_CHANGED, _check_changed, NULL); + efl_event_callback_add(check, EFL_UI_CHECK_EVENT_SELECTED_CHANGED, _check_changed, NULL); efl_gfx_hint_weight_set(check, EVAS_HINT_EXPAND, 0); efl_pack(box, check); diff --git a/src/examples/elementary/radio_cxx_example_01.cc b/src/examples/elementary/radio_cxx_example_01.cc index 1b6c659e14..90a508e4e4 100644 --- a/src/examples/elementary/radio_cxx_example_01.cc +++ b/src/examples/elementary/radio_cxx_example_01.cc @@ -33,7 +33,7 @@ efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) auto cb_val = std::bind([bx] (efl::ui::Radio &obj EINA_UNUSED) { std::cout << "val is now: " << bx.selected_value_get() << std::endl; }, std::placeholders::_1); - efl::eolian::event_add(efl::ui::Nstate::changed_event, radio, cb_val); + efl::eolian::event_add(efl::ui::Radio_Group::value_changed_event, radio, cb_val); efl::ui::Radio radio2(instantiate, win); radio2.text_set("Radio 2"); @@ -43,18 +43,18 @@ efl_main(void *data EINA_UNUSED, const Efl_Event *ev EINA_UNUSED) ic2.icon_set("file"); radio2.content_set(ic2); bx.pack_end(radio2); - efl::eolian::event_add(efl::ui::Nstate::changed_event, radio2, cb_val); + efl::eolian::event_add(efl::ui::Radio_Group::value_changed_event, radio2, cb_val); efl::ui::Radio radio3(instantiate, win); radio3.text_set("Radio 3"); radio3.state_value_set(3); bx.pack_end(radio3); - efl::eolian::event_add(efl::ui::Nstate::changed_event, radio3, cb_val); + efl::eolian::event_add(efl::ui::Radio_Group::value_changed_event, radio3, cb_val); efl::ui::Radio radio4(instantiate, win); radio4.text_set("Radio 4"); radio4.state_value_set(4); bx.pack_end(radio4); - efl::eolian::event_add(efl::ui::Nstate::changed_event, radio4, cb_val); + efl::eolian::event_add(efl::ui::Radio_Group::value_changed_event, radio4, cb_val); } EFL_MAIN() diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h index 6509423f05..6f298b636b 100644 --- a/src/lib/elementary/Efl_Ui.h +++ b/src/lib/elementary/Efl_Ui.h @@ -207,7 +207,6 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel); # include # include # include -# include # include # include diff --git a/src/lib/elementary/Elementary.h b/src/lib/elementary/Elementary.h index 2a2d986ab3..3316529acc 100644 --- a/src/lib/elementary/Elementary.h +++ b/src/lib/elementary/Elementary.h @@ -249,7 +249,6 @@ typedef Eo Efl_Ui_Focus_Manager; #include #include #include -#include #include #include diff --git a/src/lib/elementary/efl_ui_check.c b/src/lib/elementary/efl_ui_check.c index a0f643870a..7b8e4026b6 100644 --- a/src/lib/elementary/efl_ui_check.c +++ b/src/lib/elementary/efl_ui_check.c @@ -5,7 +5,6 @@ #define EFL_ACCESS_OBJECT_PROTECTED #define EFL_ACCESS_WIDGET_ACTION_PROTECTED #define ELM_LAYOUT_PROTECTED -#define EFL_UI_NSTATE_PROTECTED #define EFL_PART_PROTECTED #include diff --git a/src/lib/elementary/efl_ui_nstate.c b/src/lib/elementary/efl_ui_nstate.c deleted file mode 100644 index b44ea3b5d4..0000000000 --- a/src/lib/elementary/efl_ui_nstate.c +++ /dev/null @@ -1,155 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "elementary_config.h" -#endif - -#define EFL_UI_NSTATE_PROTECTED -#include "Elementary.h" -#include "elm_priv.h" -#include "efl_ui_nstate.eo.h" -#include "efl_ui_button_private.h" -#include "efl_ui_nstate_private.h" - -#define MY_CLASS EFL_UI_NSTATE_CLASS -#define MY_CLASS_NAME "Efl.Ui.Nstate" - - -static Eina_Bool _key_action_activate(Evas_Object *obj, const char *params); -static void _state_active(Evas_Object *obj, Efl_Ui_Nstate_Data *sd); - -static const Elm_Action key_actions[] = { - {"activate", _key_action_activate}, - {NULL, NULL} -}; - -static void -_on_state_changed(void *data, - Evas_Object *o EINA_UNUSED, - const char *emission EINA_UNUSED, - const char *source EINA_UNUSED) -{ - efl_ui_nstate_activate(data); -} - -EOLIAN static Efl_Object * -_efl_ui_nstate_efl_object_constructor(Eo *obj, Efl_Ui_Nstate_Data *pd) -{ - if (!elm_widget_theme_klass_get(obj)) - elm_widget_theme_klass_set(obj, "nstate"); - obj = efl_constructor(efl_super(obj, MY_CLASS)); - efl_canvas_object_type_set(obj, MY_CLASS_NAME); - - pd->state = 0; - // Default: 2 states - pd->nstate = 2; - - ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL); - efl_layout_signal_callback_add - (wd->resize_obj, "efl,action,state,changed", "*", obj, _on_state_changed, NULL); - - //TODO: Add ATSPI call here - - return obj; -} - -static void -_next_state_set(Efl_Ui_Nstate_Data *sd) -{ - ++sd->state; - if (sd->state == sd->nstate) sd->state = 0; -} - -static void -_state_signal_emit(Evas_Object *obj, Efl_Ui_Nstate_Data *sd) -{ - char buf[64]; - - sprintf(buf, "efl,state,changed,%d", sd->state); - elm_layout_signal_emit(obj, buf, "efl"); - edje_object_message_signal_process(elm_layout_edje_get(obj)); - elm_layout_sizing_eval(obj); -} - -static void -_state_active(Evas_Object *obj, Efl_Ui_Nstate_Data *sd) -{ - _state_signal_emit(obj, sd); - efl_event_callback_legacy_call(obj, EFL_UI_NSTATE_EVENT_CHANGED, NULL); -} - -EOLIAN static int -_efl_ui_nstate_count_get(const Eo *obj EINA_UNUSED, Efl_Ui_Nstate_Data *pd) -{ - return pd->nstate; -} - -EOLIAN static void -_efl_ui_nstate_count_set(Eo *obj EINA_UNUSED, Efl_Ui_Nstate_Data *pd, int nstate) -{ - if (pd->nstate == nstate) return; - - pd->nstate = nstate; - pd->state = 0; -} - -EOLIAN static int -_efl_ui_nstate_value_get(const Eo *obj EINA_UNUSED, Efl_Ui_Nstate_Data *pd) -{ - return pd->state; -} - -static Eina_Bool -_is_valid_state(Efl_Ui_Nstate_Data *sd, int state) -{ - if (sd->state == state || (state < 0 || state >= sd->nstate)) - return EINA_FALSE; - - return EINA_TRUE; -} - -EOLIAN static void -_efl_ui_nstate_value_set(Eo *obj, Efl_Ui_Nstate_Data *pd, int state) -{ - if (!_is_valid_state(pd, state)) return; - - pd->state = state; - _state_active(obj, pd); -} - -EOLIAN static Eina_Error -_efl_ui_nstate_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Nstate_Data *pd) -{ - Eina_Error int_ret = EFL_UI_THEME_APPLY_ERROR_GENERIC; - - int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS)); - if (int_ret == EFL_UI_THEME_APPLY_ERROR_GENERIC) return int_ret; - - _state_signal_emit(obj, pd); - - return int_ret; -} - -static Eina_Bool -_key_action_activate(Evas_Object *obj, const char *params EINA_UNUSED) -{ - efl_ui_nstate_activate(obj); - return EINA_TRUE; -} - -EOLIAN static void -_efl_ui_nstate_activate(Eo *obj, Efl_Ui_Nstate_Data *_pd) -{ - _next_state_set(_pd); - _state_active(obj, _pd); -} - -EOLIAN static void -_efl_ui_nstate_class_constructor(Efl_Class *klass) -{ - evas_smart_legacy_type_register(MY_CLASS_NAME, klass); -} - -/* Standard widget overrides */ - -ELM_WIDGET_KEY_DOWN_DEFAULT_IMPLEMENT(efl_ui_nstate, Efl_Ui_Nstate_Data) - -#include "efl_ui_nstate.eo.c" diff --git a/src/lib/elementary/efl_ui_nstate.eo b/src/lib/elementary/efl_ui_nstate.eo deleted file mode 100644 index dd72d8e992..0000000000 --- a/src/lib/elementary/efl_ui_nstate.eo +++ /dev/null @@ -1,39 +0,0 @@ -class @beta Efl.Ui.Nstate extends Efl.Ui.Button -{ - [[Efl UI nstate class]] - methods { - activate @protected { - [[Activate widget]] - } - @property count { - [[Maximum number of states]] - set { - } - get { - } - values { - nstate: int; [[The number of states.]] - } - } - @property value { - set { - [[Set the particular state given in (0...nstate}.]] - } - get { - [[Get the state value.]] - } - values { - state: int; [[The state.]] - } - } - } - implements { - class.constructor; - Efl.Object.constructor; - Efl.Ui.Widget.theme_apply; - Efl.Ui.Widget.widget_input_event_handler; - } - events { - changed: void; [[Called when the value changed.]] - } -} diff --git a/src/lib/elementary/efl_ui_nstate.h b/src/lib/elementary/efl_ui_nstate.h deleted file mode 100644 index 1d16c1f1c4..0000000000 --- a/src/lib/elementary/efl_ui_nstate.h +++ /dev/null @@ -1,24 +0,0 @@ -/** - * @defgroup Elm_Nstate Nstate - * @ingroup Elementary - * - * @image html nstate_inheritance_tree.png - * @image latex nstate_inheritance_tree.eps - * - * @image html img/widget/nstate/preview-00.png - * @image latex img/widget/nstate/preview-00.eps - * - * A Nstate is a widget which displays one of the state among states defined by user. - * - * This widget inherits from the @ref Button, so that all the functions acting on @ref Button also work for nstate objects. - * - * This widget emits the following signals, besides the ones sent from - * @ref Button: - * - @c "state,changed" - whenever state of nstate is changed - * - * Default content parts of the nstate widget that you can use are the - * the same that you use with the @ref Button - * @{ - */ - -#include "efl_ui_nstate.eo.h" diff --git a/src/lib/elementary/efl_ui_nstate_private.h b/src/lib/elementary/efl_ui_nstate_private.h deleted file mode 100644 index a976592b72..0000000000 --- a/src/lib/elementary/efl_ui_nstate_private.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef EFL_UI_NSTATE_PRIVATE_H -#define EFL_UI_NSTATE_PRIVATE_H - -#include "Elementary.h" - -/* DO NOT USE THIS HEADER UNLESS YOU ARE PREPARED FOR BREAKING OF YOUR - * CODE. THIS IS ELEMENTARY'S INTERNAL WIDGET API (for now) AND IS NOT - * FINAL. CALL elm_widget_api_check(ELM_INTERNAL_API_VERSION) TO CHECK - * IT AT RUNTIME. - */ - -/** - * @addtogroup Widget - * @{ - * - * @section efl-ui-nstate-class The Efl Ui Nstate Class - * - */ - -/** - * Base widget smart data extended with nstate instance data. - */ -typedef struct _Efl_Ui_Nstate_Data -{ - int nstate; - int state; -} Efl_Ui_Nstate_Data; -/** - * @} - */ - -#define EFL_UI_NSTATE_DATA_GET(o, sd) \ - Efl_Ui_Nstate_Data * sd = efl_data_scope_get(o, EFL_UI_NSTATE_CLASS) - -#define EFL_UI_NSTATE_DATA_GET_OR_RETURN(o, ptr) \ - EFL_UI_NSTATE_DATA_GET(o, ptr); \ - if (EINA_UNLIKELY(!ptr)) \ - { \ - ERR("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return; \ - } - -#define EFL_UI_NSTATE_DATA_GET_OR_RETURN_VAL(o, ptr, val) \ - EFL_UI_NSTATE_DATA_GET(o, ptr); \ - if (EINA_UNLIKELY(!ptr)) \ - { \ - ERR("No widget data for object %p (%s)", \ - o, evas_object_type_get(o)); \ - return val; \ - } - -#define EFL_UI_NSTATE_CHECK(obj) \ - if (EINA_UNLIKELY(!efl_isa((obj), EFL_UI_NSTATE_CLASS))) \ - return; - -#endif diff --git a/src/lib/elementary/elm_dayselector.c b/src/lib/elementary/elm_dayselector.c index d01495219c..fb5fb5cdf8 100644 --- a/src/lib/elementary/elm_dayselector.c +++ b/src/lib/elementary/elm_dayselector.c @@ -235,7 +235,7 @@ _elm_dayselector_content_set(Eo *obj, Elm_Dayselector_Data *sd, const char *item char buf[1024]; Elm_Dayselector_Item_Data *it = NULL; - EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(content, EFL_UI_NSTATE_CLASS), EINA_FALSE); + EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(content, EFL_UI_CHECK_CLASS), EINA_FALSE); if (!item) return EINA_FALSE; day = atoi(item + (strlen(item) - 1)); diff --git a/src/lib/elementary/meson.build b/src/lib/elementary/meson.build index 3cd4f68b6b..9e88e4c9b6 100644 --- a/src/lib/elementary/meson.build +++ b/src/lib/elementary/meson.build @@ -49,7 +49,6 @@ pub_eo_files = [ 'efl_ui_image_zoomable.eo', 'efl_ui_layout.eo', 'efl_ui_layout_base.eo', - 'efl_ui_nstate.eo', 'efl_ui_navigation_bar.eo', 'efl_ui_navigation_bar_part.eo', 'efl_ui_navigation_bar_part_back_button.eo', @@ -372,7 +371,6 @@ elementary_headers_unstable = [ 'efl_ui_widget_scroller.h', 'efl_ui_widget_scroll_manager.h', 'efl_ui_widget_pan.h', - 'efl_ui_nstate_private.h', 'Efl_Ui.h', 'efl_ui_tab_pager_private.h', 'efl_ui_tab_bar_private.h', @@ -514,7 +512,6 @@ elementary_pub_headers = [ 'elm_notify.h', 'elm_notify_common.h', 'elm_notify_legacy.h', - 'efl_ui_nstate.h', 'elm_object.h', 'elm_object_item.h', 'elm_panel.h', @@ -806,7 +803,6 @@ elementary_src = [ 'elm_menu.c', 'elm_module.c', 'elm_notify.c', - 'efl_ui_nstate.c', 'elm_panel.c', 'efl_ui_panes.c', 'elm_photo.c', From 2506b9e66138ec327f49deb256bc1015f40aa670 Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Thu, 27 Jun 2019 10:09:05 +0900 Subject: [PATCH 12/36] dummy_test_object: remove @owned on iterator @owned on iterator (view-only container) is removed based on 5b00dc344febd4004f268d8d76a05f7579d08288 --- src/tests/efl_mono/dummy_test_object.eo | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo index ad859c6b11..56fa844b96 100644 --- a/src/tests/efl_mono/dummy_test_object.eo +++ b/src/tests/efl_mono/dummy_test_object.eo @@ -876,7 +876,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_int_in_own { params { - @in itr: iterator @owned; + @in itr: iterator @owned; } return: bool; } @@ -896,7 +896,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_int_out_own { params { - @out itr: iterator @owned; + @out itr: iterator @owned; } return: bool; } @@ -909,7 +909,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { } eina_iterator_int_return_own { - return: iterator @owned; + return: iterator @owned; } /* String */ @@ -922,7 +922,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_str_in_own { params { - @in itr: iterator @owned; + @in itr: iterator @owned; } return: bool; } @@ -942,7 +942,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_str_out_own { params { - @out itr: iterator @owned; + @out itr: iterator @owned; } return: bool; } @@ -955,7 +955,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { } eina_iterator_str_return_own { - return: iterator @owned; + return: iterator @owned; } /* Object */ @@ -968,7 +968,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_obj_in_own { params { - @in itr: iterator @owned; + @in itr: iterator @owned; } return: bool; } @@ -988,7 +988,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_obj_out_own { params { - @out itr: iterator @owned; + @out itr: iterator @owned; } return: bool; } @@ -1001,7 +1001,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { } eina_iterator_obj_return_own { - return: iterator @owned; + return: iterator @owned; } /* Function Pointer */ From 35a5ed14942600626ab5c257288867e3e75039fb Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Wed, 26 Jun 2019 21:43:19 +0900 Subject: [PATCH 13/36] evas svg: remove unnecessary initialization. --- src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c index 9c63d0bdbd..0bd37248d6 100644 --- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c +++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c @@ -995,9 +995,9 @@ _create_node(Svg_Node *parent, Svg_Node_Type type) // update the default value of stroke and fill //https://www.w3.org/TR/SVGTiny12/painting.html#SpecifyingPaint // default fill color is black - node->style->fill.paint.r = 0; - node->style->fill.paint.g = 0; - node->style->fill.paint.b = 0; + //node->style->fill.paint.r = 0; + //node->style->fill.paint.g = 0; + //node->style->fill.paint.b = 0; node->style->fill.paint.none = EINA_FALSE; // default fill opacity is 1 node->style->fill.opacity = 255; From 7fcf887b6380efa43be6cdea91f85078a83d29dd Mon Sep 17 00:00:00 2001 From: Hermet Park Date: Thu, 27 Jun 2019 13:16:36 +0900 Subject: [PATCH 14/36] evas svg: fix missing node opacity attribute. Any svg node could have its opacity value, we missed implementing it. If a node have a opacity, it's opacity could be multiply with fill and stroke colors. @fix --- src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c | 8 ++++++++ src/static_libs/vg_common/vg_common.h | 1 + src/static_libs/vg_common/vg_common_svg.c | 12 ++++++++++++ 3 files changed, 21 insertions(+) diff --git a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c index 0bd37248d6..32bfb17d76 100644 --- a/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c +++ b/src/modules/evas/vg_loaders/svg/evas_vg_load_svg.c @@ -887,6 +887,12 @@ _handle_fill_rule_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, cons node->style->fill.fill_rule = _to_fill_rule(value); } +static void +_handle_opacity_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value) +{ + node->style->opacity = _to_opacity(value); +} + static void _handle_fill_opacity_attr(Evas_SVG_Loader *loader EINA_UNUSED, Svg_Node* node, const char *value) { @@ -915,6 +921,7 @@ static const struct { STYLE_DEF(fill, fill), STYLE_DEF(fill-rule, fill_rule), STYLE_DEF(fill-opacity, fill_opacity), + STYLE_DEF(opacity, opacity), STYLE_DEF(stroke, stroke), STYLE_DEF(stroke-width, stroke_width), STYLE_DEF(stroke-linejoin, stroke_linejoin), @@ -1001,6 +1008,7 @@ _create_node(Svg_Node *parent, Svg_Node_Type type) node->style->fill.paint.none = EINA_FALSE; // default fill opacity is 1 node->style->fill.opacity = 255; + node->style->opacity = 255; // default fill rule is nonzero node->style->fill.fill_rule = EFL_GFX_FILL_RULE_WINDING; diff --git a/src/static_libs/vg_common/vg_common.h b/src/static_libs/vg_common/vg_common.h index fc8d566144..731a8d2796 100644 --- a/src/static_libs/vg_common/vg_common.h +++ b/src/static_libs/vg_common/vg_common.h @@ -272,6 +272,7 @@ struct _Svg_Style_Property int r; int g; int b; + int opacity; }; struct _Svg_Node diff --git a/src/static_libs/vg_common/vg_common_svg.c b/src/static_libs/vg_common/vg_common_svg.c index d14d9dd847..e753e229d0 100644 --- a/src/static_libs/vg_common/vg_common_svg.c +++ b/src/static_libs/vg_common/vg_common_svg.c @@ -183,6 +183,8 @@ _eet_for_style_property(void) EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "r", r, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "g", g, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "b", b, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "opacity", opacity, EET_T_INT); + // for fill EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.flags", fill.flags, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(eet, Svg_Style_Property, "fill.paint.r", fill.paint.r, EET_T_INT); @@ -731,6 +733,15 @@ _apply_vg_property(Svg_Node *node, Efl_VG *vg, Efl_VG *parent, Vg_File_Data *vg_ style->fill.paint.b, style->fill.opacity); } + //apply node opacity + if (style->opacity < 255) + { + int r, g, b, a; + efl_gfx_color_get(vg, &r, &g, &b, &a); + float fa = ((float) style->opacity / 255); + efl_gfx_color_set(vg, ((float) r) * fa, ((float) g) * fa, ((float) b) * fa, ((float) a) * fa); + } + efl_gfx_shape_stroke_width_set(vg, style->stroke.width); efl_gfx_shape_stroke_cap_set(vg, style->stroke.cap); efl_gfx_shape_stroke_join_set(vg, style->stroke.join); @@ -906,6 +917,7 @@ _create_node(Svg_Node *parent, Svg_Node_Type type) // default line join is miter node->style->stroke.join = EFL_GFX_JOIN_MITER; node->style->stroke.scale = 1.0; + node->style->opacity = 255; node->parent = parent; node->type = type; From 25c86c88bebf97f270bb782eb77eadf0f804555f Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 26 Jun 2019 12:22:26 -0400 Subject: [PATCH 15/36] tests: remove correct callback in slider event test typo Reviewed-by: Chris Michael Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9185 --- src/tests/elementary/elm_test_slider.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/elementary/elm_test_slider.c b/src/tests/elementary/elm_test_slider.c index e4ef256ea6..7bc6fb84f3 100644 --- a/src/tests/elementary/elm_test_slider.c +++ b/src/tests/elementary/elm_test_slider.c @@ -133,7 +133,7 @@ slider_change(void *data) static void events_norendered(void *data, Evas *e, void *event_info EINA_UNUSED) { - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, norendered); + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, events_norendered); ecore_job_add(slider_change, data); } From 14ac6a9e9ed761f6d1e975babea77090fc1e422e Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 26 Jun 2019 12:23:32 -0400 Subject: [PATCH 16/36] tests/elm: add helper function for simplifying getting to event triggering the usual method is calc -> post render -> job to ensure everything is set up. this simplifies getting to that job. Reviewed-by: Chris Michael Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9186 --- src/tests/elementary/suite_helpers.c | 25 +++++++++++++++++++++++++ src/tests/elementary/suite_helpers.h | 1 + 2 files changed, 26 insertions(+) diff --git a/src/tests/elementary/suite_helpers.c b/src/tests/elementary/suite_helpers.c index e5d43c38b9..6b7ffebc78 100644 --- a/src/tests/elementary/suite_helpers.c +++ b/src/tests/elementary/suite_helpers.c @@ -358,3 +358,28 @@ fail_on_errors_setup(void) eina_log_abort_on_critical_level_set(2); eina_log_abort_on_critical_set(1); } + +static void +next_event_job() +{ + ecore_main_loop_quit(); +} + +static void +events_norendered(void *data EINA_UNUSED, Evas *e, void *event_info EINA_UNUSED) +{ + evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, events_norendered); + ecore_job_add(next_event_job, NULL); +} + +void +get_me_to_those_events(Eo *obj) +{ + Evas *e = obj; + + if (!efl_isa(obj, EFL_CANVAS_SCENE_INTERFACE)) + e = evas_object_evas_get(obj); + evas_smart_objects_calculate(e); + evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, events_norendered, NULL); + ecore_main_loop_begin(); +} diff --git a/src/tests/elementary/suite_helpers.h b/src/tests/elementary/suite_helpers.h index 75cc0487d3..12536d3884 100644 --- a/src/tests/elementary/suite_helpers.h +++ b/src/tests/elementary/suite_helpers.h @@ -10,4 +10,5 @@ void *real_timer_add(double in, Ecore_Task_Cb cb, void *data); void fail_on_errors_teardown(void); void fail_on_errors_setup(void); +void get_me_to_those_events(Eo *obj); #endif From 39833fe168699b4970567f0748b1b6f5e903df54 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 26 Jun 2019 13:00:58 -0400 Subject: [PATCH 17/36] tests/efl_ui: add suite_helpers.h to efl_ui_suite.h no need to manually include this for every file Reviewed-by: Chris Michael Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9187 --- src/tests/elementary/efl_ui_suite.c | 1 - src/tests/elementary/efl_ui_suite.h | 1 + src/tests/elementary/efl_ui_test_active_view.c | 1 - src/tests/elementary/efl_ui_test_focus.c | 1 - src/tests/elementary/efl_ui_test_radio_group.c | 1 - src/tests/elementary/efl_ui_test_widget.c | 1 - 6 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/tests/elementary/efl_ui_suite.c b/src/tests/elementary/efl_ui_suite.c index e25c4aa688..6365f85a56 100644 --- a/src/tests/elementary/efl_ui_suite.c +++ b/src/tests/elementary/efl_ui_suite.c @@ -3,7 +3,6 @@ #endif #include "efl_ui_suite.h" -#include "suite_helpers.h" #include "eo_internal.h" static const Efl_Test_Case etc[] = { diff --git a/src/tests/elementary/efl_ui_suite.h b/src/tests/elementary/efl_ui_suite.h index fff7c6566f..8dd4f80cc7 100644 --- a/src/tests/elementary/efl_ui_suite.h +++ b/src/tests/elementary/efl_ui_suite.h @@ -6,6 +6,7 @@ #define EFL_NOLEGACY_API_SUPPORT #include #include "../efl_check.h" +#include "suite_helpers.h" #define ck_assert_strn_eq(s1, s2, len) \ { \ diff --git a/src/tests/elementary/efl_ui_test_active_view.c b/src/tests/elementary/efl_ui_test_active_view.c index 44c5250bb5..447fe90e26 100644 --- a/src/tests/elementary/efl_ui_test_active_view.c +++ b/src/tests/elementary/efl_ui_test_active_view.c @@ -5,7 +5,6 @@ #include #include "efl_ui_suite.h" #include "eo_internal.h" -#include "suite_helpers.h" EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_view_manager, "efl_ui_active_view_view_manager", EFL_UI_ACTIVE_VIEW_VIEW_MANAGER_CLASS); EFL_CLASS_SIMPLE_CLASS(efl_ui_active_view_indicator, "efl_ui_active_view_indicator", EFL_UI_ACTIVE_VIEW_INDICATOR_CLASS); diff --git a/src/tests/elementary/efl_ui_test_focus.c b/src/tests/elementary/efl_ui_test_focus.c index 8e754592e8..814ab5c690 100644 --- a/src/tests/elementary/efl_ui_test_focus.c +++ b/src/tests/elementary/efl_ui_test_focus.c @@ -1,5 +1,4 @@ #include "efl_ui_test_focus_common.h" -#include "suite_helpers.h" EFL_START_TEST(focus_unregister_twice) { diff --git a/src/tests/elementary/efl_ui_test_radio_group.c b/src/tests/elementary/efl_ui_test_radio_group.c index d0d66c4fa6..c13d17b7c7 100644 --- a/src/tests/elementary/efl_ui_test_radio_group.c +++ b/src/tests/elementary/efl_ui_test_radio_group.c @@ -4,7 +4,6 @@ #include #include "efl_ui_suite.h" -#include "suite_helpers.h" static Eo *win, *radio_group; diff --git a/src/tests/elementary/efl_ui_test_widget.c b/src/tests/elementary/efl_ui_test_widget.c index 3390a81a73..23118fee86 100644 --- a/src/tests/elementary/efl_ui_test_widget.c +++ b/src/tests/elementary/efl_ui_test_widget.c @@ -7,7 +7,6 @@ #include #include "efl_ui_suite.h" #include "eo_internal.h" -#include "suite_helpers.h" typedef struct { Efl_Ui_Widget *btn1, *btn2; From 4c15ef65dd693a65a88603d1716fd6f36020decc Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 26 Jun 2019 13:01:56 -0400 Subject: [PATCH 18/36] tests/elm: replace bespoke win/loop fast-forwarding with helper function now we can consistently do event emissions inline in tests using much simpler code Reviewed-by: Chris Michael Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9188 --- src/tests/elementary/efl_ui_test_win.c | 10 +-- src/tests/elementary/elm_test_entry.c | 29 +++------ src/tests/elementary/elm_test_slider.c | 87 ++++++++++---------------- 3 files changed, 42 insertions(+), 84 deletions(-) diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index cfc57a7834..bc795ed237 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -95,13 +95,6 @@ EFL_START_TEST(efl_ui_win_test_object_focus) EFL_END_TEST -static void -prepare_window_norendered(void *data EINA_UNUSED, Evas *e, void *event_info EINA_UNUSED) -{ - efl_task_end(efl_app_main_get()); - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, prepare_window_norendered); -} - static void create_environment(Eo **win, Eo **rect) { @@ -110,8 +103,7 @@ create_environment(Eo **win, Eo **rect) efl_canvas_object_seat_focus_add(*rect, NULL); efl_gfx_entity_geometry_set(*win, EINA_RECT(0, 0, 200, 200)); efl_gfx_entity_geometry_set(*rect, EINA_RECT(0, 0, 200, 200)); - evas_event_callback_add(evas_object_evas_get(*win), EVAS_CALLBACK_RENDER_POST, prepare_window_norendered, NULL); - efl_loop_begin(efl_main_loop_get()); + get_me_to_those_events(evas_object_evas_get(*win)); } EFL_START_TEST(efl_ui_win_test_efl_input_interface_focus) diff --git a/src/tests/elementary/elm_test_entry.c b/src/tests/elementary/elm_test_entry.c index 48e31d0b3c..1b383b2936 100644 --- a/src/tests/elementary/elm_test_entry.c +++ b/src/tests/elementary/elm_test_entry.c @@ -400,29 +400,14 @@ end_test() return EINA_FALSE; } -static void -mag_job(void *e) -{ - evas_event_feed_mouse_out(e, 0, NULL); - evas_event_feed_mouse_in(e, 0, NULL); - evas_event_feed_mouse_move(e, 200, 100, 0, NULL); - evas_event_feed_mouse_down(e, 1, 0, 0, NULL); - real_timer_add(elm_config_longpress_timeout_get() + 0.1, end_test, NULL); -} - -static void -norendered(void *data EINA_UNUSED, Evas *e, void *event_info EINA_UNUSED) -{ - ecore_job_add(mag_job, e); - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, norendered); -} - EFL_START_TEST(elm_entry_magnifier) { Evas_Object *win, *entry; + Evas *e; char buf[4096]; win = win_add_focused(NULL, "entry", ELM_WIN_BASIC); + e = evas_object_evas_get(win); evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); entry = elm_entry_add(win); @@ -466,9 +451,13 @@ EFL_START_TEST(elm_entry_magnifier) evas_object_show(win); evas_object_resize(entry, 600, 400); evas_object_resize(win, 600, 400); - evas_smart_objects_calculate(evas_object_evas_get(win)); - evas_event_callback_add(evas_object_evas_get(win), EVAS_CALLBACK_RENDER_POST, norendered, NULL); - ecore_main_loop_begin(); + get_me_to_those_events(e); + + evas_event_feed_mouse_out(e, 0, NULL); + evas_event_feed_mouse_in(e, 0, NULL); + evas_event_feed_mouse_move(e, 200, 100, 0, NULL); + evas_event_feed_mouse_down(e, 1, 0, 0, NULL); + real_timer_add(elm_config_longpress_timeout_get() + 0.1, end_test, NULL); } EFL_END_TEST diff --git a/src/tests/elementary/elm_test_slider.c b/src/tests/elementary/elm_test_slider.c index 7bc6fb84f3..14035b4e48 100644 --- a/src/tests/elementary/elm_test_slider.c +++ b/src/tests/elementary/elm_test_slider.c @@ -41,35 +41,13 @@ EFL_START_TEST(elm_atspi_role_get) } EFL_END_TEST -static Evas_Object *fslider, *scroller; - -static void -mag_job(void *e) -{ - int x, y, w, h; - ck_assert_int_eq(elm_object_scroll_hold_get(scroller), 0); - evas_event_feed_mouse_in(e, 0, NULL); - evas_object_geometry_get(fslider, &x, &y, &w, &h); - evas_event_feed_mouse_move(e, x+w/2, y+h/2, 0, NULL); - //ensure that the scroller is on hold - ck_assert_int_eq(elm_object_scroll_hold_get(scroller), 1); - evas_event_feed_mouse_move(e, x+w+w/2, y+h+h/2, 0, NULL); - ck_assert_int_eq(elm_object_scroll_hold_get(scroller), 0); - ecore_main_loop_quit(); -} - -static void -norendered(void *data EINA_UNUSED, Evas *e, void *event_info EINA_UNUSED) -{ - ecore_job_add(mag_job, e); - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, norendered); -} - EFL_START_TEST(elm_slider_in_scroller) { - Evas_Object *win, *slider, *box; + Evas_Object *win, *slider, *box, *scroller, *fslider; + Evas *e; win = win_add(NULL, "slider", ELM_WIN_BASIC); + e = evas_object_evas_get(win); evas_object_size_hint_weight_set(win, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); scroller = elm_scroller_add(win); @@ -96,11 +74,18 @@ EFL_START_TEST(elm_slider_in_scroller) evas_object_resize(win, 100, 100); evas_object_show(win); - evas_smart_objects_calculate(evas_object_evas_get(win)); - evas_event_callback_add(evas_object_evas_get(win), EVAS_CALLBACK_RENDER_POST, norendered, NULL); + get_me_to_those_events(scroller); - elm_run(); + int x, y, w, h; + ck_assert_int_eq(elm_object_scroll_hold_get(scroller), 0); + evas_event_feed_mouse_in(e, 0, NULL); + evas_object_geometry_get(fslider, &x, &y, &w, &h); + evas_event_feed_mouse_move(e, x+w/2, y+h/2, 0, NULL); + //ensure that the scroller is on hold + ck_assert_int_eq(elm_object_scroll_hold_get(scroller), 1); + evas_event_feed_mouse_move(e, x+w+w/2, y+h+h/2, 0, NULL); + ck_assert_int_eq(elm_object_scroll_hold_get(scroller), 0); } EFL_END_TEST @@ -110,38 +95,19 @@ static void slider_changed(void *data EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) { event_counter++; - if (event_counter == 2) ecore_main_loop_quit(); - else evas_object_smart_callback_del(obj, "changed", slider_changed); -} - -static void -slider_change(void *data) -{ - int x, y, w, h; - int sx, sy, sw, sh; - Evas *e = evas_object_evas_get(data); - - evas_object_geometry_get(elm_object_part_content_get(data, "elm.swallow.bar"), &x, &y, &w, &h); - evas_object_geometry_get(data, &sx, &sy, &sw, &sh); - evas_event_feed_mouse_in(e, 0, NULL); - evas_event_feed_mouse_move(e, x + (w / 2), y + (h / 2), 0, NULL); - evas_event_feed_mouse_down(e, 1, 0, 0, NULL); - evas_event_feed_mouse_move(e, sx + (sw / 2), sy + (sh / 2), 0, NULL); - evas_event_feed_mouse_up(e, 1, 0, 0, NULL); -} - -static void -events_norendered(void *data, Evas *e, void *event_info EINA_UNUSED) -{ - evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, events_norendered); - ecore_job_add(slider_change, data); + if (event_counter == 1) + evas_object_smart_callback_del(obj, "changed", slider_changed); + else if (event_counter == 2) + ecore_main_loop_quit(); } EFL_START_TEST(elm_slider_events) { Evas_Object *win, *slider; + Evas *e; win = win_add(NULL, "slider", ELM_WIN_BASIC); + e = evas_object_evas_get(win); slider = elm_slider_add(win); evas_object_smart_callback_add(slider, "changed", slider_changed, NULL); @@ -151,8 +117,19 @@ EFL_START_TEST(elm_slider_events) evas_object_resize(slider, 400, 100); evas_object_resize(win, 400, 100); edje_object_message_signal_process(elm_layout_edje_get(slider)); - evas_smart_objects_calculate(evas_object_evas_get(win)); - evas_event_callback_add(evas_object_evas_get(win), EVAS_CALLBACK_RENDER_POST, events_norendered, slider); + get_me_to_those_events(slider); + + + int x, y, w, h; + int sx, sy, sw, sh; + + evas_object_geometry_get(elm_object_part_content_get(slider, "elm.swallow.bar"), &x, &y, &w, &h); + evas_object_geometry_get(slider, &sx, &sy, &sw, &sh); + evas_event_feed_mouse_in(e, 0, NULL); + evas_event_feed_mouse_move(e, x + (w / 2), y + (h / 2), 0, NULL); + evas_event_feed_mouse_down(e, 1, 0, 0, NULL); + evas_event_feed_mouse_move(e, sx + (sw / 2), sy + (sh / 2), 0, NULL); + evas_event_feed_mouse_up(e, 1, 0, 0, NULL); ecore_main_loop_begin(); ck_assert_int_eq(event_counter, 2); } From f8aa44eef72c6e9fdf9e1a4848614243cbe09f53 Mon Sep 17 00:00:00 2001 From: Stefan Schmidt Date: Thu, 20 Jun 2019 08:48:30 +0200 Subject: [PATCH 19/36] ci: travis: update last jobs from Fedora 29 to 30 docker image With the specsuite tests fixed now we can see that the build also works with Fedora 30, so we can update the last missing jobs not having it. Signed-off-by: Stefan Schmidt Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9193 --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 749f55d6f9..9af193ac9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,12 +52,12 @@ jobs: - os: linux env: DISTRO=Fedora30 CI_BUILD_TYPE=options-disabled - os: linux - env: DISTRO=Fedora29 CI_BUILD_TYPE=wayland + env: DISTRO=Fedora30 CI_BUILD_TYPE=wayland - os: linux - env: DISTRO=Fedora29 CI_BUILD_TYPE=default + env: DISTRO=Fedora30 CI_BUILD_TYPE=default - os: linux if: type = cron - env: DISTRO=Fedora29 CI_BUILD_TYPE=release-ready + env: DISTRO=Fedora30 CI_BUILD_TYPE=release-ready - os: linux if: type = cron env: DISTRO=Ubuntu1804 From 3edf75c319c47df598efd55aa6771d8d58c52bb4 Mon Sep 17 00:00:00 2001 From: Jongmin Lee Date: Thu, 27 Jun 2019 08:26:55 +0000 Subject: [PATCH 20/36] meson: add some config definitions Some config definitions used in source code could not be defined during build config process. - HAVE_XATTR - HAVE_CIPHER - HAVE_SIGNATURE - BUILD_ECORE_EVAS_EWS Reviewed-by: Marcel Hollerbach Reviewed-by: Vincent Torri Differential Revision: https://phab.enlightenment.org/D9192 --- header_checks/meson.build | 4 ++++ meson.build | 5 +++++ src/modules/ecore_evas/meson.build | 2 ++ 3 files changed, 11 insertions(+) diff --git a/header_checks/meson.build b/header_checks/meson.build index 8ead497882..21545607b8 100644 --- a/header_checks/meson.build +++ b/header_checks/meson.build @@ -194,6 +194,10 @@ if (cc.has_header('sys/mman.h')) config_h.set10('HAVE_MMAN_H', true) endif +if config_h.has('HAVE_LISTXATTR') and config_h.has('HAVE_SETXATTR') and config_h.has('HAVE_GETXATTR') + config_h.set10('HAVE_XATTR', true) +endif + regexp = [] if sys_windows == true regexp = cc.find_library('regex', diff --git a/meson.build b/meson.build index 96b33180ed..a6febe01d0 100644 --- a/meson.build +++ b/meson.build @@ -225,6 +225,11 @@ elif (get_option('crypto') == 'openssl') config_h.set('HAVE_OPENSSL', '1') endif +if get_option('crypto') != '' + config_h.set('HAVE_CIPHER', '1') + config_h.set('HAVE_SIGNATURE', '1') +endif + config_h.set_quoted('SHARED_LIB_SUFFIX', '.'+sys_lib_extension) config_h.set_quoted('MOD_SUFFIX', '.'+sys_mod_extension) config_h.set_quoted('EXE_SUFFIX', '.'+sys_exe_extension) diff --git a/src/modules/ecore_evas/meson.build b/src/modules/ecore_evas/meson.build index 7a9d6979da..78a9b35d13 100644 --- a/src/modules/ecore_evas/meson.build +++ b/src/modules/ecore_evas/meson.build @@ -44,3 +44,5 @@ if get_option('vnc-server') subdir(join_paths('vnc_server')) endif + +config_h.set('BUILD_ECORE_EVAS_EWS', '1') From e399bdd6ec493d302e3d5c402e5953de8f783880 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Wed, 26 Jun 2019 10:30:35 -0400 Subject: [PATCH 21/36] evas_events: implement POINTER_CANCEL event it looks like this was left out during initial writing of eo-based eventing, but based on the description, the intent was to have a separate cancel event which was emitted just prior to the 'up' event using the existing state Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9184 --- src/lib/evas/canvas/evas_events.c | 94 +++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 31 deletions(-) diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c index 9d40007709..adb53c56f4 100644 --- a/src/lib/evas/canvas/evas_events.c +++ b/src/lib/evas/canvas/evas_events.c @@ -814,7 +814,7 @@ static void _evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e, Efl_Input_Pointer *parent_ev, Evas_Pointer_Data *pdata, - int event_id) + int event_id, Eina_Bool cancel) { Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); Evas_Object *eo_src = _evas_object_image_source_get(eo_obj); @@ -853,7 +853,7 @@ _evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e, ev->device); continue; } - if (((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) || + if ((!cancel) && ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) || (obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) && (obj_pdata->mouse_grabbed > 0)) { @@ -864,12 +864,15 @@ _evas_event_source_mouse_up_events(Evas_Object *eo_obj, Evas *eo_e, ev->cur = point; pointer_mode = obj_pdata->pointer_mode; _evas_event_havemap_adjust_f(eo_child, child, &ev->cur, obj_pdata->mouse_grabbed); - evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_UP, evt, - event_id, EFL_EVENT_POINTER_UP); + if (cancel) + efl_event_callback_call(eo_child, EFL_EVENT_POINTER_CANCEL, evt); + else + evas_object_event_callback_call(eo_child, child, EVAS_CALLBACK_MOUSE_UP, evt, + event_id, EFL_EVENT_POINTER_UP); if (e->delete_me) break; if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN) { - if (pdata->seat->nogrep > 0) pdata->seat->nogrep--; + if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--; break; } } @@ -1755,9 +1758,10 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data Efl_Input_Pointer *evt; Eina_List *l, *copy; Evas_Object *eo_obj; - int event_id, b; + int event_id = 0, b; Evas *eo_e; Evas_Pointer_Data *pdata; + Eina_Bool cancel; static const int value_flags = _efl_input_value_mask(EFL_INPUT_VALUE_TIMESTAMP) | @@ -1773,20 +1777,29 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data if (!pdata) return; b = ev->button; - DBG("ButtonEvent:up time=%u x=%d y=%d button=%d downs=%d", - ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs); + cancel = ev->action == EFL_POINTER_ACTION_CANCEL; + if (cancel) + DBG("ButtonEvent:cancel time=%u x=%d y=%d button=%d downs=%d", + ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs); + else + DBG("ButtonEvent:up time=%u x=%d y=%d button=%d downs=%d", + ev->timestamp, pdata->seat->x, pdata->seat->y, b, pdata->seat->downs); if ((b < 1) || (b > 32)) return; if (pdata->seat->downs <= 0) return; - pdata->button &= ~(1u << (b - 1)); - pdata->seat->downs--; + if (!cancel) + { + pdata->button &= ~(1u << (b - 1)); + pdata->seat->downs--; + } if (e->is_frozen) return; e->last_timestamp = ev->timestamp; eo_e = e->evas; evt = ev->eo; - event_id = _evas_object_event_new(); + if (!cancel) + event_id = _evas_object_event_new(); ev->cur.x = pdata->seat->x; ev->cur.y = pdata->seat->y; @@ -1798,8 +1811,9 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data if (ev->device) efl_ref(ev->device); _evas_walk(e); - /* update released touch point */ - _evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_UP); + if (!cancel) + /* update released touch point */ + _evas_touch_point_update(eo_e, 0, pdata->seat->x, pdata->seat->y, EVAS_TOUCH_POINT_UP); copy = evas_event_list_copy(pdata->seat->object.in); EINA_LIST_FOREACH(copy, l, eo_obj) { @@ -1815,7 +1829,7 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data ev->device); continue; } - if (((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) || + if ((!cancel) && ((obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_AUTOGRAB) || (obj_pdata->pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN)) && (obj_pdata->mouse_grabbed > 0)) { @@ -1829,29 +1843,35 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data ev->cur.x = pdata->seat->x; ev->cur.y = pdata->seat->y; _evas_event_havemap_adjust_f(eo_obj, obj, &ev->cur, obj_pdata->mouse_grabbed); - evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_UP, evt, - event_id, EFL_EVENT_POINTER_UP); + if (cancel) + efl_event_callback_call(eo_obj, EFL_EVENT_POINTER_CANCEL, evt); + else + evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_MOUSE_UP, evt, + event_id, EFL_EVENT_POINTER_UP); if ((obj->proxy->is_proxy) && (obj->proxy->src_events)) - _evas_event_source_mouse_up_events(eo_obj, eo_e, evt, pdata, event_id); + _evas_event_source_mouse_up_events(eo_obj, eo_e, evt, pdata, event_id, cancel); if (e->delete_me) break; } if (pointer_mode == EVAS_OBJECT_POINTER_MODE_NOGRAB_NO_REPEAT_UPDOWN) { - if (pdata->seat->nogrep > 0) pdata->seat->nogrep--; + if ((!cancel) && (pdata->seat->nogrep > 0)) pdata->seat->nogrep--; break; } } eina_list_free(copy); - e->last_mouse_up_counter++; - _evas_post_event_callback_call(eo_e, e, event_id); - - if (pdata->seat->mouse_grabbed == 0) - _post_up_handle(e, evt, pdata); - - if (pdata->seat->mouse_grabbed < 0) + if (!cancel) { - ERR("BUG? pdata->seat->mouse_grabbed (=%d) < 0!", - pdata->seat->mouse_grabbed); + e->last_mouse_up_counter++; + _evas_post_event_callback_call(eo_e, e, event_id); + + if (pdata->seat->mouse_grabbed == 0) + _post_up_handle(e, evt, pdata); + + if (pdata->seat->mouse_grabbed < 0) + { + ERR("BUG? pdata->seat->mouse_grabbed (=%d) < 0!", + pdata->seat->mouse_grabbed); + } } /* remove released touch point from the touch point list */ _evas_touch_point_remove(eo_e, 0); @@ -1863,7 +1883,7 @@ _canvas_event_feed_mouse_up_internal(Evas_Public_Data *e, Efl_Input_Pointer_Data static void _canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data, - Eina_Bool down, Efl_Input_Device *device) + Eina_Bool down, Efl_Input_Device *device, Eina_Bool cancel) { Efl_Input_Pointer_Data *ev = NULL; Efl_Input_Pointer *evt; @@ -1879,7 +1899,10 @@ _canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags, ev->data = (void *) data; ev->timestamp = timestamp; ev->device = efl_ref(device ? device : _evas_event_legacy_device_get(eo_e, EINA_TRUE)); - ev->action = down ? EFL_POINTER_ACTION_DOWN : EFL_POINTER_ACTION_UP; + if (cancel) + ev->action = EFL_POINTER_ACTION_CANCEL; + else + ev->action = down ? EFL_POINTER_ACTION_DOWN : EFL_POINTER_ACTION_UP; ev->button = b; ev->button_flags = flags; ev->radius = 1; @@ -1890,12 +1913,21 @@ _canvas_event_feed_mouse_updown(Eo *eo_e, int b, Evas_Button_Flags flags, //ev->window_pos = ?; //ev->fake = 1; + /* first, send the cancel action through to trigger POINTER_CANCEL on all + * relevant objects. + * this does not change canvas state in any way. + * note that the 'down' branch can only occur if 'cancel' is not true + */ if (down) _canvas_event_feed_mouse_down_internal(e, ev); else _canvas_event_feed_mouse_up_internal(e, ev); efl_unref(evt); + + /* next, emit actual up event and perform state changes */ + if (cancel) + _canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, device, EINA_FALSE); } static void @@ -1903,7 +1935,7 @@ _canvas_event_feed_mouse_updown_legacy(Eo *eo_e, int b, Evas_Button_Flags flags, unsigned int timestamp, const void *data, Eina_Bool down) { - _canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, NULL); + _canvas_event_feed_mouse_updown(eo_e, b, flags, timestamp, data, down, NULL, EINA_FALSE); } EAPI void @@ -1954,7 +1986,7 @@ _canvas_event_feed_mouse_cancel_internal(Evas_Public_Data *e, Efl_Input_Pointer_ for (i = 0; i < 32; i++) { if ((pdata->button & (1u << i))) - _canvas_event_feed_mouse_updown(eo_e, i + 1, 0, ev->timestamp, ev->data, 0, ev->device); + _canvas_event_feed_mouse_updown(eo_e, i + 1, 0, ev->timestamp, ev->data, 0, ev->device, EINA_TRUE); } ev->action = EFL_POINTER_ACTION_CANCEL; From 5e54ad67ecc34fafce30bc9cd913624fe91a737d Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Mon, 24 Jun 2019 18:18:09 +0200 Subject: [PATCH 22/36] efl_input_interface: verify check cancel event this verifies that EFL_EVENT_POINTER_CANCEL is emitted correctly. Reviewed-by: Mike Blumenkrantz Differential Revision: https://phab.enlightenment.org/D9171 --- src/tests/elementary/efl_ui_test_win.c | 76 ++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/src/tests/elementary/efl_ui_test_win.c b/src/tests/elementary/efl_ui_test_win.c index bc795ed237..aecd1362d0 100644 --- a/src/tests/elementary/efl_ui_test_win.c +++ b/src/tests/elementary/efl_ui_test_win.c @@ -358,6 +358,81 @@ EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_wheel) ck_assert_int_eq(pointer_wheel, EINA_TRUE); } EFL_END_TEST + + +static void +_check_ptr_cancel_down_event(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 1); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_DOWN); + *called = EINA_TRUE; +} + +static void +_check_ptr_cancel_event(void *data, const Efl_Event *ev) +{ + int *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 1); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_CANCEL ); + ck_assert_int_eq(*called, 0); + *called = 1; +} + +static void +_check_ptr_cancel_up_event(void *data, const Efl_Event *ev) +{ + Eina_Bool *called = data; + ck_assert_int_eq(efl_input_timestamp_get(ev->info), TIMESTAMP); + ck_assert_int_eq(efl_input_pointer_wheel_delta_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_wheel_horizontal_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_double_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_triple_click_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_button_flags_get(ev->info), 0); + ck_assert_int_eq(efl_input_pointer_touch_id_get(ev->info), 0); + position_eq(efl_input_pointer_position_get(ev->info), EINA_POSITION2D(20, 20)); + ck_assert_int_eq(efl_input_pointer_button_get(ev->info), 1); + ck_assert_int_eq(efl_input_pointer_action_get(ev->info), EFL_POINTER_ACTION_UP); + ck_assert_int_eq(*called, 1); + *called = 2; +} + +EFL_START_TEST(efl_ui_win_test_efl_input_interface_pointer_cancel) +{ + Efl_Ui_Win *win; + Eina_Bool called_down = EINA_FALSE; + int called; + Efl_Canvas_Object *rect; + create_environment(&win, &rect); + + evas_event_feed_mouse_move(evas_object_evas_get(win), 20, 20, TIMESTAMP - 1, NULL); + efl_event_callback_add(rect, EFL_EVENT_POINTER_DOWN, _check_ptr_cancel_down_event, &called_down); + evas_event_feed_mouse_down(evas_object_evas_get(win), 1, 0, TIMESTAMP, NULL); + ck_assert_int_eq(called_down, EINA_TRUE); + called = EINA_FALSE; + + efl_event_callback_add(rect, EFL_EVENT_POINTER_CANCEL, _check_ptr_cancel_event, &called); + efl_event_callback_add(rect, EFL_EVENT_POINTER_UP, _check_ptr_cancel_up_event, &called); + evas_event_feed_mouse_cancel(evas_object_evas_get(win), TIMESTAMP, NULL); + ck_assert_int_eq(called, 2); +} +EFL_END_TEST void efl_ui_test_win(TCase *tc) { @@ -371,4 +446,5 @@ efl_ui_test_win(TCase *tc) tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_up); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_in_out); tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_wheel); + tcase_add_test(tc, efl_ui_win_test_efl_input_interface_pointer_cancel); } From 920a1b4a52b96a84d724583f442e867c4f39168b Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 27 Jun 2019 16:48:37 +0200 Subject: [PATCH 23/36] meson: disable xattr on macos macos has a different implementation than linux for xattr. This commit disables XATTR again for macos. --- header_checks/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/header_checks/meson.build b/header_checks/meson.build index 21545607b8..ff5b21ee0c 100644 --- a/header_checks/meson.build +++ b/header_checks/meson.build @@ -194,7 +194,7 @@ if (cc.has_header('sys/mman.h')) config_h.set10('HAVE_MMAN_H', true) endif -if config_h.has('HAVE_LISTXATTR') and config_h.has('HAVE_SETXATTR') and config_h.has('HAVE_GETXATTR') +if sys_linux and config_h.has('HAVE_LISTXATTR') and config_h.has('HAVE_SETXATTR') and config_h.has('HAVE_GETXATTR') config_h.set10('HAVE_XATTR', true) endif From 967e32d27a2a324a37f8f2b5cc5c07ff063f5f82 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Thu, 27 Jun 2019 13:49:42 -0300 Subject: [PATCH 24/36] csharp: Update after iterator changes Summary: Iterator and Accessors are views only, not owning the data they point to. Also updated the tests by handling some test data that were leaking. Fixes T8036 Reviewers: vitor.sousa, felipealmeida Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers, segfaultxavi, q66 Tags: #efl Maniphest Tasks: T8036 Differential Revision: https://phab.enlightenment.org/D9189 --- src/bin/eolian_mono/eolian/mono/parameter.hh | 84 +++++++++++++++---- .../eolian/mono/struct_definition.hh | 10 ++- src/bindings/mono/eina_mono/eina_array.cs | 2 +- src/bindings/mono/eina_mono/eina_hash.cs | 4 +- src/bindings/mono/eina_mono/eina_inarray.cs | 4 +- src/bindings/mono/eina_mono/eina_inlist.cs | 2 +- src/bindings/mono/eina_mono/eina_iterator.cs | 31 +------ src/bindings/mono/eina_mono/eina_list.cs | 4 +- src/tests/efl_mono/Eina.cs | 49 ++--------- src/tests/efl_mono/dummy_test_object.c | 54 ++++++++---- src/tests/efl_mono/dummy_test_object.eo | 16 ++-- 11 files changed, 140 insertions(+), 120 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index ca3c573df7..f16c740f28 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -604,8 +604,6 @@ struct native_convert_in_variable_generator } else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *" || param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *" - || param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *" - || param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *" ) { attributes::complex_type_def const* complex = efl::eina::get(¶m.type.original_type); @@ -618,6 +616,19 @@ struct native_convert_in_variable_generator << ");\n" ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); } + else if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *" + || param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *" + ) + { + attributes::complex_type_def const* complex = efl::eina::get(¶m.type.original_type); + if (!complex) + return false; + return as_generator( + "var " << string << " = new " << type << "(" << escape_keyword(param.param_name) + << ", " << (param.type.has_own ? "true" : "false") + << ");\n" + ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); + } else if (param.type.c_type == "Eina_Value") { return as_generator( @@ -706,6 +717,13 @@ struct convert_in_variable_generator escape_keyword(param.param_name) << ".Own = false;\n" ).generate(sink, attributes::unused, context)) return false; + + // Iterators and Accessors can't own their content. + if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *" + || param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *" + ) + return true; + if (complex->subtypes.front().has_own && !as_generator( escape_keyword(param.param_name) << ".OwnContent = false;\n" ).generate(sink, attributes::unused, context)) @@ -937,14 +955,6 @@ struct convert_out_assign_generator || param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT) || param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT) || param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT) - || param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT) ) { attributes::complex_type_def const* complex = efl::eina::get(¶m.type.original_type); @@ -957,6 +967,25 @@ struct convert_out_assign_generator << ");\n" ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context); } + else if (param_is_acceptable(param, "Eina_Iterator *", WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "Eina_Iterator *", !WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "const Eina_Iterator *", WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "const Eina_Iterator *", !WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "Eina_Accessor *", !WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "const Eina_Accessor *", WANT_OWN, WANT_OUT) + || param_is_acceptable(param, "const Eina_Accessor *", !WANT_OWN, WANT_OUT) + ) + { + attributes::complex_type_def const* complex = efl::eina::get(¶m.type.original_type); + if (!complex) + return false; + return as_generator( + string << " = new " << type << "(" << string + << ", " << (param.type.has_own ? "true" : "false") + << ");\n" + ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context); + } else if (param_is_acceptable(param, "Eina_Value", WANT_OWN, WANT_OUT) || param_is_acceptable(param, "Eina_Value", !WANT_OWN, WANT_OUT)) { @@ -1057,9 +1086,7 @@ struct convert_return_generator } else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *" || ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *" - || ret_type.c_type == "Eina_Iterator *" || ret_type.c_type == "const Eina_Iterator *" - || ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *" - ) + ) { attributes::complex_type_def const* complex = efl::eina::get(&ret_type.original_type); if (!complex) @@ -1070,6 +1097,17 @@ struct convert_return_generator .generate(sink, ret_type, context)) return false; } + else if(ret_type.c_type == "Eina_Iterator *" || ret_type.c_type == "const Eina_Iterator *" + || ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *" + ) + { + attributes::complex_type_def const* complex = efl::eina::get(&ret_type.original_type); + if (!complex) + return false; + if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"} << ");\n") + .generate(sink, ret_type, context)) + return false; + } else if (ret_type.c_type != "void") { return as_generator("return _ret_var;\n").generate(sink, ret_type, context); @@ -1199,6 +1237,13 @@ struct native_convert_out_assign_generator string << ".Own = false;\n" ).generate(sink, outvar, context)) return false; + + // Iterators and Accessors can't own their content. + if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *" + || param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *" + ) + return true; + if (complex->subtypes.front().has_own && !as_generator( string << ".OwnContent = false;\n" ).generate(sink, outvar, context)) @@ -1319,9 +1364,16 @@ struct native_convert_return_generator if (ret_type.has_own && !as_generator("_ret_var.Own = false; ") .generate(sink, attributes::unused, context)) return false; - if (complex->subtypes.front().has_own && !as_generator("_ret_var.OwnContent = false; ") - .generate(sink, attributes::unused, context)) - return false; + + // Iterators and Accessors can't own their content. + if (ret_type.c_type != "Eina_Iterator *" && ret_type.c_type != "const Eina_Iterator *" + || ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *" + ) + { + if (complex->subtypes.front().has_own && !as_generator("_ret_var.OwnContent = false; ") + .generate(sink, attributes::unused, context)) + return false; + } return as_generator("return _ret_var.Handle;\n") .generate(sink, attributes::unused, context); diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index ba50f2d2f9..204484c2b0 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -171,8 +171,7 @@ struct to_external_field_convert_generator return false; } else if (complex && (complex->outer.base_type == "array" - || complex->outer.base_type == "list" - || complex->outer.base_type == "iterator")) + || complex->outer.base_type == "list")) { // Always assumes pointer if (!as_generator( @@ -187,6 +186,13 @@ struct to_external_field_convert_generator .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) return false; } + else if (complex && complex->outer.base_type == "iterator") + { + if (!as_generator( + indent << scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false);\n") + .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) + return false; + } else if (field.type.is_ptr && helpers::need_pointer_conversion(regular) && !helpers::need_struct_conversion(regular)) { if (!as_generator( diff --git a/src/bindings/mono/eina_mono/eina_array.cs b/src/bindings/mono/eina_mono/eina_array.cs index e3bd852e2b..e75ca6ae7a 100644 --- a/src/bindings/mono/eina_mono/eina_array.cs +++ b/src/bindings/mono/eina_mono/eina_array.cs @@ -315,7 +315,7 @@ public class Array : IEnumerable, IDisposable public Eina.Iterator GetIterator() { - return new Eina.Iterator(eina_array_iterator_new(Handle), true, false); + return new Eina.Iterator(eina_array_iterator_new(Handle), true); } public IEnumerator GetEnumerator() diff --git a/src/bindings/mono/eina_mono/eina_hash.cs b/src/bindings/mono/eina_mono/eina_hash.cs index 8b3c1e7db5..1617eba961 100644 --- a/src/bindings/mono/eina_mono/eina_hash.cs +++ b/src/bindings/mono/eina_mono/eina_hash.cs @@ -485,12 +485,12 @@ public class Hash : IEnumerable>, IDi public Eina.Iterator Keys() { - return new Eina.Iterator(EinaHashIteratorKeyNew(Handle), true, false); + return new Eina.Iterator(EinaHashIteratorKeyNew(Handle), true); } public Eina.Iterator Values() { - return new Eina.Iterator(eina_hash_iterator_data_new(Handle), true, false); + return new Eina.Iterator(eina_hash_iterator_data_new(Handle), true); } public IEnumerator> GetEnumerator() diff --git a/src/bindings/mono/eina_mono/eina_inarray.cs b/src/bindings/mono/eina_mono/eina_inarray.cs index c7f3151ac1..70f99cb8ca 100644 --- a/src/bindings/mono/eina_mono/eina_inarray.cs +++ b/src/bindings/mono/eina_mono/eina_inarray.cs @@ -358,12 +358,12 @@ public class Inarray : IEnumerable, IDisposable public Eina.Iterator GetIterator() { - return new Eina.Iterator(eina_inarray_iterator_new(Handle), true, false); + return new Eina.Iterator(eina_inarray_iterator_new(Handle), true); } public Eina.Iterator GetReversedIterator() { - return new Eina.Iterator(eina_inarray_iterator_reversed_new(Handle), true, false); + return new Eina.Iterator(eina_inarray_iterator_reversed_new(Handle), true); } public IEnumerator GetEnumerator() diff --git a/src/bindings/mono/eina_mono/eina_inlist.cs b/src/bindings/mono/eina_mono/eina_inlist.cs index 0cc9bae6a0..5f94f44f6a 100644 --- a/src/bindings/mono/eina_mono/eina_inlist.cs +++ b/src/bindings/mono/eina_mono/eina_inlist.cs @@ -314,7 +314,7 @@ public class Inlist : IEnumerable, IDisposable public Eina.Iterator GetIterator() { - return new Eina.Iterator(eina_inlist_iterator_wrapper_new_custom_export_mono(Handle), true, false); + return new Eina.Iterator(eina_inlist_iterator_wrapper_new_custom_export_mono(Handle), true); } public IEnumerator GetEnumerator() diff --git a/src/bindings/mono/eina_mono/eina_iterator.cs b/src/bindings/mono/eina_mono/eina_iterator.cs index 05b5408606..0ca4293c8f 100644 --- a/src/bindings/mono/eina_mono/eina_iterator.cs +++ b/src/bindings/mono/eina_mono/eina_iterator.cs @@ -33,20 +33,11 @@ public class Iterator : IEnumerable, IDisposable { public IntPtr Handle {get;set;} = IntPtr.Zero; public bool Own {get;set;} = true; - public bool OwnContent {get;set;} = false; public Iterator(IntPtr handle, bool own) { Handle = handle; Own = own; - OwnContent = own; - } - - public Iterator(IntPtr handle, bool own, bool ownContent) - { - Handle = handle; - Own = own; - OwnContent = ownContent; } ~Iterator() @@ -63,14 +54,6 @@ public class Iterator : IEnumerable, IDisposable return; } - if (OwnContent) - { - for (IntPtr data; eina_iterator_next(h, out data);) - { - NativeFree(data); - } - } - if (Own) { if (disposing) @@ -102,16 +85,9 @@ public class Iterator : IEnumerable, IDisposable return h; } - public void SetOwnership(bool ownAll) - { - Own = ownAll; - OwnContent = ownAll; - } - - public void SetOwnership(bool own, bool ownContent) + public void SetOwnership(bool own) { Own = own; - OwnContent = ownContent; } public bool Next(out T res) @@ -125,11 +101,6 @@ public class Iterator : IEnumerable, IDisposable res = NativeToManaged(data); - if (OwnContent) - { - NativeFree(data); - } - return true; } diff --git a/src/bindings/mono/eina_mono/eina_list.cs b/src/bindings/mono/eina_mono/eina_list.cs index 4b9e5f5856..4c25c25e62 100644 --- a/src/bindings/mono/eina_mono/eina_list.cs +++ b/src/bindings/mono/eina_mono/eina_list.cs @@ -353,12 +353,12 @@ public class List : IEnumerable, IDisposable public Eina.Iterator GetIterator() { - return new Eina.Iterator(eina_list_iterator_new(Handle), true, false); + return new Eina.Iterator(eina_list_iterator_new(Handle), true); } public Eina.Iterator GetReversedIterator() { - return new Eina.Iterator(eina_list_iterator_reversed_new(Handle), true, false); + return new Eina.Iterator(eina_list_iterator_reversed_new(Handle), true); } public IEnumerator GetEnumerator() diff --git a/src/tests/efl_mono/Eina.cs b/src/tests/efl_mono/Eina.cs index 1705c7ab83..c15e062002 100644 --- a/src/tests/efl_mono/Eina.cs +++ b/src/tests/efl_mono/Eina.cs @@ -3129,14 +3129,12 @@ class TestEinaIterator var itr = arr.GetIterator(); Test.Assert(itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); Test.Assert(arr.OwnContent); Test.Assert(t.EinaIteratorIntIn(itr)); Test.Assert(itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); Test.Assert(arr.OwnContent); @@ -3150,20 +3148,18 @@ class TestEinaIterator var arr = new Eina.Array(); arr.Append(base_seq_int); var itr = arr.GetIterator(); - arr.OwnContent = false; - itr.OwnContent = true; Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); + Test.Assert(arr.OwnContent); + // Will take ownership of the Iterator Test.Assert(t.EinaIteratorIntInOwn(itr)); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); + // Content must continue to be owned by the array + Test.Assert(arr.OwnContent); itr.Dispose(); arr.Dispose(); @@ -3178,9 +3174,7 @@ class TestEinaIterator Test.Assert(t.EinaIteratorIntOut(out itr)); - Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); int idx = 0; foreach (int e in itr) @@ -3203,7 +3197,6 @@ class TestEinaIterator Test.Assert(t.EinaIteratorIntOutOwn(out itr)); Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); int idx = 0; foreach (int e in itr) @@ -3223,7 +3216,6 @@ class TestEinaIterator var itr = t.EinaIteratorIntReturn(); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); int idx = 0; foreach (int e in itr) @@ -3245,7 +3237,6 @@ class TestEinaIterator var itr = t.EinaIteratorIntReturnOwn(); Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); int idx = 0; foreach (int e in itr) @@ -3268,14 +3259,12 @@ class TestEinaIterator var itr = arr.GetIterator(); Test.Assert(itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); Test.Assert(arr.OwnContent); Test.Assert(t.EinaIteratorStrIn(itr)); Test.Assert(itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); Test.Assert(arr.OwnContent); @@ -3289,24 +3278,16 @@ class TestEinaIterator var arr = new Eina.Array(); arr.Append(base_seq_str); var itr = arr.GetIterator(); - arr.OwnContent = false; - itr.OwnContent = true; Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); + Test.Assert(arr.OwnContent); Test.Assert(t.EinaIteratorStrInOwn(itr)); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); - Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); - Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); + Test.Assert(arr.OwnContent); itr.Dispose(); arr.Dispose(); @@ -3322,7 +3303,6 @@ class TestEinaIterator Test.Assert(t.EinaIteratorStrOut(out itr)); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); int idx = 0; foreach (string e in itr) @@ -3345,7 +3325,6 @@ class TestEinaIterator Test.Assert(t.EinaIteratorStrOutOwn(out itr)); Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); int idx = 0; foreach (string e in itr) @@ -3365,7 +3344,6 @@ class TestEinaIterator var itr = t.EinaIteratorStrReturn(); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); int idx = 0; foreach (string e in itr) @@ -3387,7 +3365,6 @@ class TestEinaIterator var itr = t.EinaIteratorStrReturnOwn(); Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); int idx = 0; foreach (string e in itr) @@ -3410,14 +3387,12 @@ class TestEinaIterator var itr = arr.GetIterator(); Test.Assert(itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); Test.Assert(arr.OwnContent); Test.Assert(t.EinaIteratorObjIn(itr)); Test.Assert(itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); Test.Assert(arr.OwnContent); @@ -3431,20 +3406,16 @@ class TestEinaIterator var arr = new Eina.Array(); arr.Append(BaseSeqObj()); var itr = arr.GetIterator(); - arr.OwnContent = false; - itr.OwnContent = true; Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); + Test.Assert(arr.OwnContent); Test.Assert(t.EinaIteratorObjInOwn(itr)); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); Test.Assert(arr.Own); - Test.Assert(!arr.OwnContent); + Test.Assert(arr.OwnContent); itr.Dispose(); arr.Dispose(); @@ -3460,7 +3431,6 @@ class TestEinaIterator Test.Assert(t.EinaIteratorObjOut(out itr)); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); var base_seq_obj = BaseSeqObj(); @@ -3485,7 +3455,6 @@ class TestEinaIterator Test.Assert(t.EinaIteratorObjOutOwn(out itr)); Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); var base_seq_obj = BaseSeqObj(); @@ -3507,7 +3476,6 @@ class TestEinaIterator var itr = t.EinaIteratorObjReturn(); Test.Assert(!itr.Own); - Test.Assert(!itr.OwnContent); var base_seq_obj = BaseSeqObj(); @@ -3531,7 +3499,6 @@ class TestEinaIterator var itr = t.EinaIteratorObjReturnOwn(); Test.Assert(itr.Own); - Test.Assert(itr.OwnContent); var base_seq_obj = BaseSeqObj(); diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c index fa5d01888a..4fdc69bbed 100644 --- a/src/tests/efl_mono/dummy_test_object.c +++ b/src/tests/efl_mono/dummy_test_object.c @@ -16,6 +16,9 @@ typedef struct Dummy_Test_Object_Data int iface_prop; Eo *provider; Eo *iface_provider; + + // Containers passed to C# as iterator/accessors + Eina_Array *out_array; } Dummy_Test_Object_Data; static @@ -97,6 +100,9 @@ _dummy_test_object_efl_object_destructor(Eo *obj, Dummy_Test_Object_Data *pd) pd->list_for_accessor = NULL; } + if (pd->out_array) + eina_array_free(pd->out_array); + efl_destructor(efl_super(obj, DUMMY_TEST_OBJECT_CLASS)); } @@ -2695,7 +2701,7 @@ static Eina_Iterator *_iterator_int_in_own_to_check = NULL; Eina_Bool _dummy_test_object_eina_iterator_int_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Iterator *itr) { - Eina_Bool r = _iterator_int_equal(itr, base_seq_int, base_seq_int_size, EINA_TRUE); + Eina_Bool r = _iterator_int_equal(itr, base_seq_int, base_seq_int_size, EINA_FALSE); _iterator_int_in_own_to_check = itr; return r; } @@ -2746,9 +2752,12 @@ Eina_Bool _dummy_test_object_eina_iterator_int_out_own(EINA_UNUSED Eo *obj, EINA { if (!itr) return EINA_FALSE; - Eina_Array *arr = _iterator_int_eina_array_new(); + if (pd->out_array) + eina_array_free(pd->out_array); - *itr = eina_array_iterator_new(arr); + pd->out_array = _iterator_int_eina_array_new(); + + *itr = eina_array_iterator_new(pd->out_array); return EINA_TRUE; } @@ -2786,8 +2795,11 @@ Eina_Bool _dummy_test_object_check_eina_iterator_int_return(EINA_UNUSED Eo *obj, Eina_Iterator *_dummy_test_object_eina_iterator_int_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) { - Eina_Array *arr = _iterator_int_eina_array_new(); - return eina_array_iterator_new(arr); + if (pd->out_array) + eina_array_free(pd->out_array); + + pd->out_array = _iterator_int_eina_array_new(); + return eina_array_iterator_new(pd->out_array); } // String // @@ -2853,7 +2865,7 @@ static Eina_Iterator *_iterator_str_in_own_to_check = NULL; Eina_Bool _dummy_test_object_eina_iterator_str_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Iterator *itr) { - Eina_Bool r = _iterator_str_equal(itr, base_seq_str, base_seq_str_size, EINA_TRUE); + Eina_Bool r = _iterator_str_equal(itr, base_seq_str, base_seq_str_size, EINA_FALSE); _iterator_str_in_own_to_check = itr; return r; } @@ -2904,9 +2916,12 @@ Eina_Bool _dummy_test_object_eina_iterator_str_out_own(EINA_UNUSED Eo *obj, EINA { if (!itr) return EINA_FALSE; - Eina_Array *arr = _iterator_str_eina_array_new(); + if (pd->out_array) + eina_array_free(pd->out_array); - *itr = eina_array_iterator_new(arr); + pd->out_array = _iterator_str_eina_array_new(); + + *itr = eina_array_iterator_new(pd->out_array); return EINA_TRUE; } @@ -2944,8 +2959,11 @@ Eina_Bool _dummy_test_object_check_eina_iterator_str_return(EINA_UNUSED Eo *obj, Eina_Iterator *_dummy_test_object_eina_iterator_str_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) { - Eina_Array *arr = _iterator_str_eina_array_new(); - return eina_array_iterator_new(arr); + if (pd->out_array) + eina_array_free(pd->out_array); + + pd->out_array = _iterator_str_eina_array_new(); + return eina_array_iterator_new(pd->out_array); } // Object // @@ -3015,7 +3033,7 @@ static Eina_Iterator *_iterator_obj_in_own_to_check = NULL; Eina_Bool _dummy_test_object_eina_iterator_obj_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Iterator *itr) { - Eina_Bool r = _iterator_obj_equal(itr, base_seq_obj, base_seq_obj_size, EINA_TRUE); + Eina_Bool r = _iterator_obj_equal(itr, base_seq_obj, base_seq_obj_size, EINA_FALSE); _iterator_obj_in_own_to_check = itr; return r; } @@ -3066,9 +3084,12 @@ Eina_Bool _dummy_test_object_eina_iterator_obj_out_own(EINA_UNUSED Eo *obj, EINA { if (!itr) return EINA_FALSE; - Eina_Array *arr = _iterator_obj_eina_array_new(); + if (pd->out_array) + eina_array_free(pd->out_array); - *itr = eina_array_iterator_new(arr); + pd->out_array = _iterator_obj_eina_array_new(); + + *itr = eina_array_iterator_new(pd->out_array); return EINA_TRUE; } @@ -3106,8 +3127,11 @@ Eina_Bool _dummy_test_object_check_eina_iterator_obj_return(EINA_UNUSED Eo *obj, Eina_Iterator *_dummy_test_object_eina_iterator_obj_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) { - Eina_Array *arr = _iterator_obj_eina_array_new(); - return eina_array_iterator_new(arr); + if (pd->out_array) + eina_array_free(pd->out_array); + + pd->out_array = _iterator_obj_eina_array_new(); + return eina_array_iterator_new(pd->out_array); } // // diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo index 56fa844b96..529b246418 100644 --- a/src/tests/efl_mono/dummy_test_object.eo +++ b/src/tests/efl_mono/dummy_test_object.eo @@ -869,14 +869,14 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { /* Integer */ eina_iterator_int_in { params { - @in itr: iterator; + @in itr: iterator; } return: bool; } eina_iterator_int_in_own { params { - @in itr: iterator @owned; + @in itr: iterator @owned; } return: bool; } @@ -886,7 +886,7 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_int_out { params { - @out itr: iterator; + @out itr: iterator; } return: bool; } @@ -896,20 +896,20 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { eina_iterator_int_out_own { params { - @out itr: iterator @owned; + @out itr: iterator @owned; } return: bool; } eina_iterator_int_return { - return: iterator; + return: iterator; } check_eina_iterator_int_return { return: bool; } eina_iterator_int_return_own { - return: iterator @owned; + return: iterator @owned; } /* String */ @@ -1393,9 +1393,9 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { /* Accessors */ clone_accessor { params { - @in acc: accessor; + @in acc: accessor; } - return: accessor @owned; + return: accessor @owned; } @property setter_only { From e4a5374d3ee8caba42ad973a999ba681c2f0df0a Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Thu, 27 Jun 2019 14:27:34 -0300 Subject: [PATCH 25/36] eolian_mono: small correction when checking for iterator and accessor parameters --- src/bin/eolian_mono/eolian/mono/parameter.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index f16c740f28..e1e8661bcb 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -1367,7 +1367,7 @@ struct native_convert_return_generator // Iterators and Accessors can't own their content. if (ret_type.c_type != "Eina_Iterator *" && ret_type.c_type != "const Eina_Iterator *" - || ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *" + && ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *" ) { if (complex->subtypes.front().has_own && !as_generator("_ret_var.OwnContent = false; ") From 03936c05131985a683967abc9cc1aa5ad88ff53a Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Thu, 27 Jun 2019 14:29:13 -0300 Subject: [PATCH 26/36] eolian_mono: fix to support event info which is a type defined in eo Summary: Previously, if event info was not structure and it was a type defined in eo, then the type value was not passed to the event info correctly. e.g. if event info was Efl.Ui.AlertPopupButton enum type, then default(Efl.Ui.AlertPopupButton) was always passed to event info. Now, the given type value is passed to the event info correctly. Reviewers: felipealmeida, lauromoura, vitor.sousa, bu5hm4n Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, herb, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9159 --- src/bin/eolian_mono/eolian/mono/events.hh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh index 0522a9be7a..9b4b8c362f 100644 --- a/src/bin/eolian_mono/eolian/mono/events.hh +++ b/src/bin/eolian_mono/eolian/mono/events.hh @@ -102,7 +102,13 @@ struct unpack_event_args_visitor if (eina::optional b = call_match(match_table, filter_func, accept_func)) return *b; else - return as_generator("default(" + arg_type + ")").generate(sink, attributes::unused, *context); + { + // Type defined in Eo is passed here. (e.g. enum type defined in Eo) + // Uses conversion from IntPtr with type casting to the given type. + return as_generator( + " (" << arg_type << ")evt.Info" + ).generate(sink, attributes::unused, *context); + } } bool operator()(grammar::attributes::klass_name const& cls) const { From accaaa1ff7be168a16dd682760943dee429619eb Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Thu, 27 Jun 2019 19:21:28 -0300 Subject: [PATCH 27/36] csharp: Add missing prefix to enable interpolation Reviewers: vitor.sousa Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl, #expertise_solutions Differential Revision: https://phab.enlightenment.org/D9195 --- src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs b/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs index 13a3cac865..65ae60b6bf 100644 --- a/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs +++ b/src/bindings/mono/eo_mono/FunctionWrapper_Unix.cs @@ -18,9 +18,9 @@ public partial class FunctionInterop ///A function pointer that can be used with delegates. public static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName) { - Eina.Log.Debug("searching {nativeLibraryHandle} for {functionName}"); + Eina.Log.Debug($"searching {nativeLibraryHandle} for {functionName}"); var s = FunctionInterop.dlsym(nativeLibraryHandle, functionName); - Eina.Log.Debug("searching {nativeLibraryHandle} for {functionName}, result {s}"); + Eina.Log.Debug($"searching {nativeLibraryHandle} for {functionName}, result {s}"); return s; } } From 0f514b484bb3f14ec7c7ef2882f990ff73815527 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Thu, 27 Jun 2019 19:26:44 -0300 Subject: [PATCH 28/36] csharp: Rename test util parameters Summary: Instead of 'expected' and 'actual', use 'lhs' and 'rhs', as it allows the actually expected value to be in any position. Reviewers: vitor.sousa Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl, #expertise_solutions Differential Revision: https://phab.enlightenment.org/D9196 --- src/tests/efl_mono/TestUtils.cs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/tests/efl_mono/TestUtils.cs b/src/tests/efl_mono/TestUtils.cs index b66f15a0bc..21b8ec7794 100644 --- a/src/tests/efl_mono/TestUtils.cs +++ b/src/tests/efl_mono/TestUtils.cs @@ -37,46 +37,46 @@ public static class Test throw new AssertionException($"Assertion failed: {file}:{line} ({member}) {msg}"); } - /// Asserts if expected is equal to actual, using expected.Equals(actual). - public static void AssertEquals(T expected, T actual, String msg = null, + /// Asserts if lhs is equal to rhs, using lhs.Equals(rhs). + public static void AssertEquals(T lhs, T rhs, String msg = null, [CallerLineNumber] int line = 0, [CallerFilePath] string file = null, [CallerMemberName] string member = null) { - if (expected == null && actual == null) + if (lhs == null && rhs == null) return; - if (expected == null || !expected.Equals(actual)) + if (lhs == null || !lhs.Equals(rhs)) { if (file == null) file = "(unknown file)"; if (member == null) member = "(unknown member)"; if (msg == null || msg.Length == 0) - msg = $"Expected \"{expected}\", actual \"{actual}\""; + msg = $"Left hand side \"{lhs}\", right hand side \"{rhs}\""; throw new AssertionException($"{file}:{line} ({member}) {msg}"); } } - /// Asserts if expected is not equal to actual, using !expected.Equals(actual). - public static void AssertNotEquals(T expected, T actual, String msg = null, + /// Asserts if lhs is not equal to rhs, using !lhs.Equals(rhs). + public static void AssertNotEquals(T lhs, T rhs, String msg = null, [CallerLineNumber] int line = 0, [CallerFilePath] string file = null, [CallerMemberName] string member = null) { - if (expected == null ? actual == null : expected.Equals(actual)) + if (lhs == null ? rhs == null : lhs.Equals(rhs)) { if (file == null) file = "(unknown file)"; if (member == null) member = "(unknown member)"; if (msg == null || msg.Length == 0) - msg = $"Expected \"{expected}\" shouldn't be equal to actual \"{actual}\""; + msg = $"Left hand side \"{lhs}\" shouldn't be equal to right hand side \"{rhs}\""; throw new AssertionException($"{file}:{line} ({member}) {msg}"); } } - /// Asserts if actual is near enough of expected, using the optional tolerance (default 0.00001). - public static void AssertAlmostEquals(double expected, double actual, double tolerance=0.00001, + /// Asserts if rhs is near enough of lhs, using the optional tolerance (default 0.00001). + public static void AssertAlmostEquals(double lhs, double rhs, double tolerance=0.00001, String msg = null, [CallerLineNumber] int line = 0, [CallerFilePath] string file = null, @@ -86,10 +86,10 @@ public static class Test file = "(unknown file)"; if (member == null) member = "(unknown member)"; - double difference = Math.Abs(expected - actual); + double difference = Math.Abs(lhs - rhs); if (difference > tolerance) { if (msg == null || msg.Length == 0) - msg = $"Expected \"{expected}\". Difference: \"{difference}\""; + msg = $"Left hand side \"{lhs}\". Difference: \"{difference}\""; throw new AssertionException($"{file}:{line} ({member}) {msg}"); } } From ef185e5e28d2a92944d4e072d70b21df58bab8e1 Mon Sep 17 00:00:00 2001 From: Lauro Moura Date: Thu, 27 Jun 2019 19:04:59 -0300 Subject: [PATCH 29/36] efl-mono: Fix value forwarding in promises/async Summary: Values returned from C# Then callbacks must release ownership of the underlying native value, so Eina code can clean it up nicely and avoid the Wrapper flushing it early. The same issue applied to the Async wrappers. In this case the value passed as the Task parameter could be released by an `using` block awaiting the value. Also Future creation was then-ing the wrong handle. Also add better exception messages. Reviewers: vitor.sousa, felipealmeida Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9197 --- src/bindings/mono/eina_mono/eina_promises.cs | 12 ++++++++-- src/bindings/mono/eina_mono/eina_value.cs | 24 ++++++++++++++----- src/bindings/mono/eo_mono/iwrapper.cs | 6 +++-- src/tests/efl_mono/Promises.cs | 25 ++++++++++++++++++++ 4 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/bindings/mono/eina_mono/eina_promises.cs b/src/bindings/mono/eina_mono/eina_promises.cs index 25077a3c97..34561a5b08 100644 --- a/src/bindings/mono/eina_mono/eina_promises.cs +++ b/src/bindings/mono/eina_mono/eina_promises.cs @@ -180,6 +180,8 @@ public class Promise : IDisposable { SanityChecks(); eina_promise_resolve(this.Handle, value); + // Promise will take care of releasing this value correctly. + value.ReleaseOwnership(); this.Handle = IntPtr.Zero; // Resolving a cb does *not* call its cancellation callback, so we have to release the // lambda created in the constructor for cleanup. @@ -224,11 +226,12 @@ public class Future /// public Future(IntPtr handle) { - Handle = ThenRaw(handle, (Eina.Value value) => + handle = ThenRaw(handle, (Eina.Value value) => { Handle = IntPtr.Zero; return value; }); + Handle = handle; } /// @@ -304,7 +307,12 @@ public class Future ResolvedCb cb = handle.Target as ResolvedCb; if (cb != null) { - value = cb(value); + Eina.Value managedValue = cb(value); + // Both `value` and `managedValue` will point to the same internal value data. + // Avoid C# wrapper invalidating the underlying C Eina_Value as the eina_future.c + // code will release it. + value = managedValue.GetNative(); + managedValue.ReleaseOwnership(); } else { diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs index 99cf09757d..a19d3d449b 100644 --- a/src/bindings/mono/eina_mono/eina_value.cs +++ b/src/bindings/mono/eina_mono/eina_value.cs @@ -46,6 +46,9 @@ static internal class UnsafeNativeMethods [DllImport(efl.Libs.Eina)] internal static extern void eina_value_free(IntPtr type); + [DllImport(efl.Libs.Eina)] + internal static extern IntPtr eina_value_type_name_get(IntPtr type); + [DllImport(efl.Libs.Eina)] [return: MarshalAsAttribute(UnmanagedType.U1)] internal static extern bool eina_value_convert(IntPtr handle, IntPtr convert); @@ -725,7 +728,16 @@ static class ValueTypeBridge LoadTypes(); } - return NativeToManaged[native]; + try + { + return NativeToManaged[native]; + } + catch (KeyNotFoundException ex) + { + var name_ptr = eina_value_type_name_get(native); + var name = Marshal.PtrToStringAnsi(name_ptr); + throw new Efl.EflException($"Unknown native eina value Type: 0x{native.ToInt64():x} with name {name}"); + } } public static IntPtr GetNative(ValueType valueType) @@ -978,8 +990,7 @@ public class Value : IDisposable, IComparable, IEquatable // free(), avoiding a call to eina_value_flush that would wipe the underlying value contents // for pointer types like string. tmp = MemoryNative.Alloc(Marshal.SizeOf(typeof(ValueNative))); - Marshal.StructureToPtr(value, tmp, false); // Can't get the address of a struct directly. - this.Handle = Alloc(); + Marshal.StructureToPtr(value, tmp, false); // Can't get the address of a struct directly. // Copy is used to deep copy the pointed payload (e.g. strings) inside this struct, so we can own this value. if (!eina_value_copy(tmp, this.Handle)) @@ -1482,7 +1493,7 @@ public class Value : IDisposable, IComparable, IEquatable { if (Disposed) { - throw new ObjectDisposedException(base.GetType().Name); + throw new ObjectDisposedException($"Value at 0x{this.Handle.ToInt64():x}"); } return this.Handle; @@ -1494,7 +1505,7 @@ public class Value : IDisposable, IComparable, IEquatable { if (Disposed) { - throw new ObjectDisposedException(base.GetType().Name); + throw new ObjectDisposedException($"Value at 0x{this.Handle.ToInt64():x}"); } // Can't call setup with Empty value type (would give an eina error) @@ -1540,7 +1551,7 @@ public class Value : IDisposable, IComparable, IEquatable { if (Disposed) { - throw new ObjectDisposedException(GetType().Name); + throw new ObjectDisposedException($"Value at 0x{this.Handle.ToInt64():x}"); } } @@ -1591,6 +1602,7 @@ public class Value : IDisposable, IComparable, IEquatable /// Get a ValueNative struct with the *value* pointed by this Eina.Value. public ValueNative GetNative() { + SanityChecks(); ValueNative value = (ValueNative)Marshal.PtrToStructure(this.Handle, typeof(ValueNative)); return value; } diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs index 5fe1daae91..82c08ccf3f 100644 --- a/src/bindings/mono/eo_mono/iwrapper.cs +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -530,8 +530,10 @@ public class Globals } else { - // Will mark the returned task below as completed. - tcs.SetResult(received); + // Async receiver methods may consume the value C# wrapper, like when awaiting in the start of an + // using block. In order to continue to forward the value correctly to the next futures + // in the chain, we give the Async wrapper a copy of the received wrapper. + tcs.SetResult(new Eina.Value(received)); } fulfilled = true; diff --git a/src/tests/efl_mono/Promises.cs b/src/tests/efl_mono/Promises.cs index b355a0ee3d..fc0c089e4e 100644 --- a/src/tests/efl_mono/Promises.cs +++ b/src/tests/efl_mono/Promises.cs @@ -42,6 +42,31 @@ class TestPromises Test.AssertEquals(received_value, reference_value); } + public static void test_simple_with_object() + { + bool callbackCalled = false; + Eina.Value receivedValue = null; + + Efl.Loop loop = Efl.App.AppMain; + Eina.Promise promise = new Eina.Promise(); + Eina.Future future = new Eina.Future(promise); + + future = future.Then((Eina.Value value) => { + callbackCalled = true; + receivedValue = new Eina.Value(value); + return value; + }); + + Eina.Value referenceValue = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Int32); + referenceValue.Append(32); + promise.Resolve(new Eina.Value(referenceValue)); + + loop.Iterate(); + + Test.Assert(callbackCalled, "Future callback should have been called."); + Test.AssertEquals(receivedValue, referenceValue); + } + public static void test_simple_reject() { bool callbackCalled = false; From 7b8766698ad363665264db8f5ed188e06381223b Mon Sep 17 00:00:00 2001 From: Wonki Kim Date: Fri, 28 Jun 2019 01:45:56 +0000 Subject: [PATCH 30/36] meson: remove autotools checking stuffs autotools has been removed. so that the autotools checking logic is not needed. this patch removes them. Reviewed-by: Marcel Hollerbach Differential Revision: https://phab.enlightenment.org/D9198 --- meson.build | 5 ----- meson/clean_check.sh | 3 --- 2 files changed, 8 deletions(-) delete mode 100644 meson/clean_check.sh diff --git a/meson.build b/meson.build index a6febe01d0..dfc8907c9d 100644 --- a/meson.build +++ b/meson.build @@ -8,11 +8,6 @@ if host_machine.system() == 'darwin' add_languages('objc') endif -clean_check = run_command('meson/clean_check.sh') -if clean_check.returncode() == 0 - error('Meson build requires a clean source tree') -endif - pkgconfig = import('pkgconfig') test_env = environment() diff --git a/meson/clean_check.sh b/meson/clean_check.sh deleted file mode 100644 index c054794048..0000000000 --- a/meson/clean_check.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -test -f ${MESON_SOURCE_ROOT}/configure From d3dbd5a5cdf24359d214bd487ebab6f202ff1a38 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Thu, 27 Jun 2019 08:13:04 +0200 Subject: [PATCH 31/36] evas_events: fix wrong event listening EFL_EVENT_FOCUS_IN is wrong here, EFL_EVENT_FOCUS_IN is called on object that received object focus. Not canvas focus, however, the code in the callback there seems to be mainly for canvas focus handling. Additionally, in evas_events, the event handler that was listening for the canvas focus in / out events expected a event type, which is also not correct, because the canvas focus in / out does not have one. In order to catch such errors later more easily, there is now a safety check, so we really fetched the correct seat. Reviewed-by: YeongJong Lee Differential Revision: https://phab.enlightenment.org/D9191 --- src/lib/evas/canvas/evas_events.c | 14 ++++++-------- src/lib/evas/canvas/evas_main.c | 6 +++--- src/tests/evas/evas_suite.c | 1 + src/tests/evas/evas_suite.h | 1 + src/tests/evas/evas_test_focus.c | 28 ++++++++++++++++++++++++++++ src/tests/evas/meson.build | 1 + 6 files changed, 40 insertions(+), 11 deletions(-) create mode 100644 src/tests/evas/evas_test_focus.c diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c index adb53c56f4..ca8bad2242 100644 --- a/src/lib/evas/canvas/evas_events.c +++ b/src/lib/evas/canvas/evas_events.c @@ -4245,22 +4245,20 @@ _evas_canvas_event_key_cb(void *data, const Efl_Event *event) static void _evas_canvas_event_focus_cb(void *data, const Efl_Event *event) { - Efl_Input_Device *seat = efl_input_device_get(event->info); + Efl_Input_Device *seat = efl_canvas_scene_seat_default_get(event->object); Evas_Public_Data *e = data; - if (event->desc == EFL_EVENT_FOCUS_IN) + EINA_SAFETY_ON_NULL_RETURN(seat); + + if (event->desc == EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN) { if (eina_list_data_find(e->focused_by, seat)) return; e->focused_by = eina_list_append(e->focused_by, seat); - evas_event_callback_call(e->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, - event->info); } else { if (!eina_list_data_find(e->focused_by, seat)) return; e->focused_by = eina_list_remove(e->focused_by, seat); - evas_event_callback_call(e->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, - event->info); } } @@ -4279,8 +4277,8 @@ EFL_CALLBACKS_ARRAY_DEFINE(_evas_canvas_event_pointer_callbacks, { EFL_EVENT_FINGER_UP, _evas_canvas_event_pointer_cb }, { EFL_EVENT_KEY_DOWN, _evas_canvas_event_key_cb }, { EFL_EVENT_KEY_UP, _evas_canvas_event_key_cb }, -{ EFL_EVENT_FOCUS_IN, _evas_canvas_event_focus_cb }, -{ EFL_EVENT_FOCUS_OUT, _evas_canvas_event_focus_cb }) +{ EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN, _evas_canvas_event_focus_cb }, +{ EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT, _evas_canvas_event_focus_cb }) void _evas_canvas_event_init(Evas *eo_e, Evas_Public_Data *e) diff --git a/src/lib/evas/canvas/evas_main.c b/src/lib/evas/canvas/evas_main.c index 20c93874b6..84854cddf7 100644 --- a/src/lib/evas/canvas/evas_main.c +++ b/src/lib/evas/canvas/evas_main.c @@ -857,9 +857,9 @@ static void _evas_canvas_focus_inout_dispatch(Eo *eo_e, Evas_Device *seat EINA_UNUSED, Eina_Bool in) { - efl_event_callback_call(eo_e, - in ? EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN : EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT, - NULL); + efl_event_callback_legacy_call(eo_e, + in ? EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_IN : EFL_CANVAS_SCENE_EVENT_SCENE_FOCUS_OUT, + NULL); } EOLIAN static void diff --git a/src/tests/evas/evas_suite.c b/src/tests/evas/evas_suite.c index e84d23f5dc..d1946cdeb0 100644 --- a/src/tests/evas/evas_suite.c +++ b/src/tests/evas/evas_suite.c @@ -10,6 +10,7 @@ static const Efl_Test_Case etc[] = { { "Evas", evas_test_init }, + { "Evas Focus", evas_test_focus }, { "Evas New", evas_test_new }, { "Object", evas_test_object }, { "Object Textblock", evas_test_textblock }, diff --git a/src/tests/evas/evas_suite.h b/src/tests/evas/evas_suite.h index 0da47fe13f..3b6b7bf8f9 100644 --- a/src/tests/evas/evas_suite.h +++ b/src/tests/evas/evas_suite.h @@ -4,6 +4,7 @@ #include #include "../efl_check.h" void evas_test_init(TCase *tc); +void evas_test_focus(TCase *tc); void evas_test_new(TCase *tc); void evas_test_object(TCase *tc); void evas_test_textblock(TCase *tc); diff --git a/src/tests/evas/evas_test_focus.c b/src/tests/evas/evas_test_focus.c new file mode 100644 index 0000000000..5c33bf2d41 --- /dev/null +++ b/src/tests/evas/evas_test_focus.c @@ -0,0 +1,28 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include + +#include + +#include "evas_suite.h" + +EFL_START_TEST(evas_focus) +{ + Evas *evas = evas_new(); + + evas_output_method_set(evas, evas_render_method_lookup("buffer")); + evas_focus_in(evas); + ck_assert_int_eq(evas_focus_state_get(evas), EINA_TRUE); + evas_focus_out(evas); + ck_assert_int_eq(evas_focus_state_get(evas), EINA_FALSE); + evas_focus_out(evas); + ck_assert_int_eq(evas_focus_state_get(evas), EINA_FALSE); +} +EFL_END_TEST + +void evas_test_focus(TCase *tc) +{ + tcase_add_test(tc, evas_focus); +} diff --git a/src/tests/evas/meson.build b/src/tests/evas/meson.build index 5c06ff79ff..627351b2ae 100644 --- a/src/tests/evas/meson.build +++ b/src/tests/evas/meson.build @@ -14,6 +14,7 @@ evas_suite_src = [ 'evas_test_mask.c', 'evas_test_evasgl.c', 'evas_test_matrix.c', + 'evas_test_focus.c', 'evas_tests_helpers.h', 'evas_suite.h' ] From b892fa3ce71885c1e84330202744858af35d487c Mon Sep 17 00:00:00 2001 From: Jaehyun Cho Date: Fri, 28 Jun 2019 18:15:42 +0900 Subject: [PATCH 32/36] view_manager_scroll: fix not to move view position by click Summary: Previously, view position was moved by click because transition information was initialized in mouse move instead of mouse down. Now, transition information is initialized in mouse down so view position is not moved by click. Test Plan: 1. Run Efl.Ui.Active_View Scroll 2. Click Next button 2 times 3. Click Button Page Or 3. Drag Button Page a bit to the left and click multiple times Reviewers: bu5hm4n Reviewed By: bu5hm4n Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9173 --- src/lib/elementary/efl_ui_active_view_view_manager_scroll.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c b/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c index 6918703cf1..9bff559dbb 100644 --- a/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c +++ b/src/lib/elementary/efl_ui_active_view_view_manager_scroll.c @@ -105,6 +105,10 @@ _mouse_down_cb(void *data, pd->mouse_move.active = EINA_TRUE; pd->mouse_move.from = efl_ui_active_view_active_index_get(pd->container); pd->mouse_move.mouse_start = efl_input_pointer_position_get(ev); + + pd->transition.from = pd->mouse_move.from; + pd->transition.to = pd->transition.from + 1; + pd->transition.progress = 0.0; } static void @@ -124,9 +128,7 @@ _mouse_move_cb(void *data, pos_y_diff = pd->mouse_move.mouse_start.x - pos.x; pd->transition.active = EINA_TRUE; - pd->transition.from = pd->mouse_move.from; pd->transition.progress = (double)pos_y_diff / (double)pd->page_size.w; - pd->transition.to = pd->transition.from + 1; _propagate_progress(data, pd->transition.from + pd->transition.progress); From 549c417853f8f934a8fe63cd0c0cb2d4e8e9ff01 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Fri, 28 Jun 2019 08:47:41 -0400 Subject: [PATCH 33/36] efl_ui: include here efl_ui_item Summary: this is actually a new class, it should be included here. Reviewers: zmike, stefan_schmidt Reviewed By: zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9200 --- src/lib/elementary/Efl_Ui.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/elementary/Efl_Ui.h b/src/lib/elementary/Efl_Ui.h index 6f298b636b..2647362ba5 100644 --- a/src/lib/elementary/Efl_Ui.h +++ b/src/lib/elementary/Efl_Ui.h @@ -179,6 +179,7 @@ EAPI void efl_ui_focus_relation_free(Efl_Ui_Focus_Relations *rel); # include # include # include +# include # include # include # include From b7fa7d48ac9eff4b360e83de4d974a92c84c0291 Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Fri, 28 Jun 2019 10:29:01 -0300 Subject: [PATCH 34/36] csharp: make inherited C# classes constructible from native C Summary: With this commit it is now possible for a class that inherits from a C# binding class to be instantiated from native C code. It only has to provide a constructor that receives an `Efl.Eo.EoWrapper.ConstructingHandle` struct, and which calls the base binding constructor passing it. For example: `private Type(ConstructingHandle ch) : base(ch) {}`. Add some test files to validate the proper behavior of this feature. Add some small fixes in generation contexts in order to properly generate base constructors. Depends on D9070 Test Plan: `meson test` and `make check` Reviewers: lauromoura, felipealmeida, segfaultxavi, woohyun, YOhoho Reviewed By: YOhoho Subscribers: YOhoho, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9071 --- src/bin/eolian_mono/eolian/mono/klass.hh | 24 +++- src/bindings/mono/eo_mono/EoWrapper.cs | 112 +++++++++++++++++- src/bindings/mono/eo_mono/iwrapper.cs | 11 +- src/lib/efl_mono/efl_custom_exports_mono.c | 10 ++ src/tests/efl_mono/EoConstruction.cs | 96 +++++++++++++++ .../efl_mono/dummy_constructible_object.c | 77 ++++++++++++ .../efl_mono/dummy_constructible_object.eo | 53 +++++++++ src/tests/efl_mono/dummy_test_object.c | 6 +- src/tests/efl_mono/libefl_mono_native_test.h | 1 + src/tests/efl_mono/meson.build | 3 + 10 files changed, 380 insertions(+), 13 deletions(-) create mode 100644 src/tests/efl_mono/EoConstruction.cs create mode 100644 src/tests/efl_mono/dummy_constructible_object.c create mode 100644 src/tests/efl_mono/dummy_constructible_object.eo diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index 6ac4aa1c3c..8b018f6413 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -196,6 +196,17 @@ struct klass if (!generate_fields(sink, cls, concrete_cxt)) return false; + if (!as_generator + ( + scope_tab << "/// Constructor to be used when objects are expected to be constructed from native code.\n" + << scope_tab << "/// Tag struct storing the native handle of the object being constructed.\n" + << scope_tab << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n" + << scope_tab << "{\n" + << scope_tab << "}\n\n" + ) + .generate(sink, attributes::unused, concrete_cxt)) + return false; + if (!as_generator ( scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag(concrete_cxt).actual_library_name(cls.filename) @@ -246,7 +257,7 @@ struct klass ).generate(sink, attributes::unused, concrete_cxt)) return false; - if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), context))) + if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt))) return true; if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false; @@ -318,7 +329,7 @@ struct klass ).generate(sink, attributes::unused, inherit_cxt)) return false; - if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), context))) + if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), inherit_cxt))) return true; if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false; @@ -357,7 +368,7 @@ struct klass ( indent << lit("/// Wrapper for native methods and virtual method delegates.\n") << indent << "/// For internal use by generated code only.\n" - << indent << "public " << (root ? "" : "new " ) << "class " << native_inherit_name << " " << (root ? " : Efl.Eo.NativeClass" : (": " + base_name)) <<"\n" + << indent << "public new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n" << indent << "{\n" ).generate(sink, attributes::unused, inative_cxt)) return false; @@ -396,7 +407,7 @@ struct klass ).generate(sink, attributes::unused, inative_cxt)) return false; - if(!root) + if (!root || context_find_tag(context).current_wrapper_kind != class_context::concrete) if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type));\n").generate(sink, attributes::unused, inative_cxt)) return false; @@ -492,6 +503,11 @@ struct klass << (*(scope_tab << scope_tab << constructor_invocation << "\n")) << scope_tab << scope_tab << "FinishInstantiation();\n" << scope_tab << "}\n\n" + << scope_tab << "/// Constructor to be used when objects are expected to be constructed from native code.\n" + << scope_tab << "/// Tag struct storing the native handle of the object being constructed.\n" + << scope_tab << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n" + << scope_tab << "{\n" + << scope_tab << "}\n\n" << scope_tab << "/// Initializes a new instance of the class.\n" << scope_tab << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.\n" << scope_tab << "/// The native pointer to be wrapped.\n" diff --git a/src/bindings/mono/eo_mono/EoWrapper.cs b/src/bindings/mono/eo_mono/EoWrapper.cs index b6ea619923..7e512acf56 100644 --- a/src/bindings/mono/eo_mono/EoWrapper.cs +++ b/src/bindings/mono/eo_mono/EoWrapper.cs @@ -2,6 +2,7 @@ using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Threading; +using System.Reflection; namespace Efl { @@ -18,6 +19,33 @@ public abstract class EoWrapper : IWrapper, IDisposable private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback); private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback); + + /// Constructor to be used when objects are expected to be constructed from native code. + /// For a class that inherited from an EFL# class to be properly constructed from native code + /// one must create a constructor with this signature and calls this base constructor from it. + /// This constructor will take care of calling base constructors of the native classes and + /// perform additional setup so objects are ready to use. + /// It is advisable to check for the property in the top level + /// constructor and signal an error when it has a value of IntPtr.Zero after this + /// constructor completion. + /// Warning: Do not use this constructor directly from a `new` statement. + /// Tag struct storing the native handle of the object being constructed. + protected EoWrapper(ConstructingHandle ch) + { + inherited = true; + handle = Efl.Eo.Globals.efl_constructor(Efl.Eo.Globals.efl_super(ch.NativeHandle, Efl.Eo.Globals.efl_class_get(ch.NativeHandle))); + if (handle == IntPtr.Zero) + { + Eina.Log.Warning("Natice constructor returned NULL"); + return; + } + + AddWrapperSupervisor(); + // Make an additional reference to C# + // - Will also call EVENT_OWNERSHIP_SHARED + Efl.Eo.Globals.efl_ref(handle); + } + /// Initializes a new instance of the class. /// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly. /// The native pointer to be wrapped. @@ -54,7 +82,17 @@ public abstract class EoWrapper : IWrapper, IDisposable parent_ptr = parent.NativeHandle; } - handle = Efl.Eo.Globals._efl_add_internal_start(file, line, actual_klass, parent_ptr, 1, 0); + if (!inherited) + { + handle = Efl.Eo.Globals._efl_add_internal_start(file, line, actual_klass, parent_ptr, 1, 0); + } + else + { + handle = Efl.Eo.Globals._efl_add_internal_start_bindings(file, line, actual_klass, parent_ptr, 1, 0, + Efl.Eo.Globals.efl_mono_avoid_top_level_constructor_callback_addr_get(), + IntPtr.Zero); + } + if (handle == System.IntPtr.Zero) { throw new Exception("Instantiation failed"); @@ -246,8 +284,78 @@ public abstract class EoWrapper : IWrapper, IDisposable AddNativeEventHandler("eo", "_EFL_EVENT_OWNERSHIP_SHARED", ownershipSharedDelegate, ownershipSharedDelegate); Eina.Error.RaiseIfUnhandledException(); } + + protected struct ConstructingHandle + { + public ConstructingHandle(IntPtr h) + { + NativeHandle = h; + } + + public IntPtr NativeHandle { get; set; } + } + + public abstract class NativeMethods : Efl.Eo.NativeClass + { + private static EflConstructorDelegate csharpEflConstructorStaticDelegate = new EflConstructorDelegate(Constructor); + private static Efl.Eo.NativeModule EoModule = new Efl.Eo.NativeModule("eo"); + + private delegate IntPtr EflConstructorDelegate(IntPtr obj, IntPtr pd); + + public override System.Collections.Generic.List GetEoOps(Type type) + { + var descs = new System.Collections.Generic.List(); + + descs.Add(new Efl_Op_Description() + { + api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(EoModule.Module, "efl_constructor"), + func = Marshal.GetFunctionPointerForDelegate(csharpEflConstructorStaticDelegate) + }); + + return descs; + } + + private static IntPtr Constructor(IntPtr obj, IntPtr pd) + { + try + { + var eoKlass = Efl.Eo.Globals.efl_class_get(obj); + var managedType = ClassRegister.GetManagedType(eoKlass); + if (managedType == null) + { + IntPtr nativeName = Efl.Eo.Globals.efl_class_name_get(eoKlass); + var name = Eina.StringConversion.NativeUtf8ToManagedString(nativeName); + Eina.Log.Warning($"Can't get Managed class for object handle 0x{(UInt64)obj:x} with native class [{name}]"); + return IntPtr.Zero; + } + + var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; + ConstructorInfo constructor = managedType.GetConstructor(flags, null, new Type[1] { typeof(ConstructingHandle) }, null); + if (constructor == null) + { + Eina.Log.Error($"Type {managedType.FullName} lacks a constructor that receives a ConstructingHandle. It can not be constructed from native code."); + return IntPtr.Zero; + } + + var eoWrapper = (Efl.Eo.IWrapper) constructor.Invoke(new object[1] { new ConstructingHandle(obj) }); + if (eoWrapper == null) + { + Eina.Log.Warning("Constructor was unable to create a new object"); + return IntPtr.Zero; + } + + return eoWrapper.NativeHandle; + } + catch (Exception e) + { + Eina.Log.Warning($"Inherited constructor error: {e.ToString()}"); + Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION); + return IntPtr.Zero; + } + } + } } -} // namespace Global +} // namespace Eo } // namespace Efl diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs index 82c08ccf3f..966759b314 100644 --- a/src/bindings/mono/eo_mono/iwrapper.cs +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -44,10 +44,6 @@ public class Globals public static FunctionWrapper efl_object_shutdown_ptr = new FunctionWrapper(efl.Libs.EoModule, "efl_object_shutdown"); public static void efl_object_shutdown() => efl_object_shutdown_ptr.Value.Delegate(); // [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown(); - public static FunctionWrapper<_efl_add_internal_start_delegate> _efl_add_internal_start_ptr = new FunctionWrapper<_efl_add_internal_start_delegate>(efl.Libs.EoModule, "_efl_add_internal_start"); - public delegate IntPtr - _efl_add_internal_start_delegate([MarshalAs(UnmanagedType.LPStr)] String file, int line, - IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback); [DllImport(efl.Libs.CustomExports)] public static extern IntPtr efl_mono_wrapper_supervisor_get(IntPtr eo); [DllImport(efl.Libs.CustomExports)] public static extern void efl_mono_wrapper_supervisor_set(IntPtr eo, IntPtr ws); @@ -55,6 +51,9 @@ public class Globals [DllImport(efl.Libs.Eo)] public static extern IntPtr _efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line, IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback); + [DllImport(efl.Libs.Eo)] public static extern IntPtr + _efl_add_internal_start_bindings([MarshalAs(UnmanagedType.LPStr)] String file, int line, IntPtr klass, IntPtr parent, + byte is_ref, byte is_fallback, IntPtr substitute_ctor, IntPtr data); public delegate IntPtr _efl_add_end_delegate(IntPtr eo, byte is_ref, byte is_fallback); [DllImport(efl.Libs.Eo)] public static extern IntPtr @@ -196,6 +195,10 @@ public class Globals public delegate IntPtr dlerror_delegate(); [DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror(); + [DllImport(efl.Libs.Eo)] public static extern IntPtr efl_constructor(IntPtr obj); + + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr efl_mono_avoid_top_level_constructor_callback_addr_get(); + [DllImport(efl.Libs.Eo)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool efl_event_callback_priority_add(IntPtr obj, IntPtr desc, short priority, IntPtr cb, IntPtr data); diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c index ad74babe52..8d57ad730f 100644 --- a/src/lib/efl_mono/efl_custom_exports_mono.c +++ b/src/lib/efl_mono/efl_custom_exports_mono.c @@ -166,6 +166,16 @@ EAPI Eina_Free_Cb efl_mono_native_efl_unref_addr_get() return (Eina_Free_Cb)efl_mono_thread_safe_efl_unref; } +static Eo *_efl_mono_avoid_top_level_constructor_cb(void *data EINA_UNUSED, Eo *obj) +{ + return efl_constructor(efl_super(obj, efl_class_get(obj))); +} + +EAPI Efl_Substitute_Ctor_Cb efl_mono_avoid_top_level_constructor_callback_addr_get() +{ + return &_efl_mono_avoid_top_level_constructor_cb; +} + // Iterator Wrapper // typedef struct _Eina_Iterator_Wrapper_Mono diff --git a/src/tests/efl_mono/EoConstruction.cs b/src/tests/efl_mono/EoConstruction.cs new file mode 100644 index 0000000000..4708befc5b --- /dev/null +++ b/src/tests/efl_mono/EoConstruction.cs @@ -0,0 +1,96 @@ +using System; + +class InheritedConstructibleObject : Dummy.ConstructibleObject +{ + public InheritedConstructibleObject() : base() + { + if (this.NativeConstructionCount != 1) + { + DefaultConstrutorCallCount = -100; + } + + ++DefaultConstrutorCallCount; + this.IncrementDefaultConstructionCount(); + } + + private InheritedConstructibleObject(ConstructingHandle ch) : base(ch) + { + if (this.NativeConstructionCount != 1) + { + SpecialConstrutorCallCount = -100; + } + + ++SpecialConstrutorCallCount; + this.IncrementSpecialConstructionCount(); + } + + public int DefaultConstrutorCallCount { get; set; } = 0; + public int SpecialConstrutorCallCount { get; set; } = 0; + + public bool InheritedFlag + { + get { return inherited; } + } + + public override int MultiplyIntegerValue(int v) + { + return 3 * v; + } +} + +namespace TestSuite +{ + +class TestEoConstruction +{ + public static void TestGeneratedEoDirectConstruction() + { + var obj = new Dummy.ConstructibleObject(); + Test.AssertEquals(obj.NativeConstructionCount, 1); + Test.AssertEquals(obj.DefaultConstructionCount, 0); + Test.AssertEquals(obj.SpecialConstructionCount, 0); + Test.AssertEquals(obj.MultiplyIntegerValue(21), 42); + obj.Dispose(); + } + + public static void TestInheritedEoDirectConstruction() + { + var obj = new InheritedConstructibleObject(); + Test.AssertEquals(obj.InheritedFlag, true); + Test.AssertEquals(obj.NativeConstructionCount, 1); + Test.AssertEquals(obj.DefaultConstructionCount, 1); + Test.AssertEquals(obj.SpecialConstructionCount, 0); + Test.AssertEquals(obj.DefaultConstrutorCallCount, 1); + Test.AssertEquals(obj.SpecialConstrutorCallCount, 0); + Test.AssertEquals(obj.MultiplyIntegerValue(21), 63); + obj.Dispose(); + } + + public static void TestInheritedEoIndirectConstruction() + { + var obj = new Dummy.ConstructibleObject(); + Test.AssertEquals(obj.NativeConstructionCount, 1); + Test.AssertEquals(obj.DefaultConstructionCount, 0); + Test.AssertEquals(obj.SpecialConstructionCount, 0); + Test.AssertEquals(obj.MultiplyIntegerValue(21), 42); + + var obj2 = (InheritedConstructibleObject) obj.ConstructTypeAndStore(typeof(InheritedConstructibleObject)); + Test.AssertEquals(obj2.InheritedFlag, true); + Test.AssertEquals(obj2.NativeConstructionCount, 1); + Test.AssertEquals(obj2.DefaultConstructionCount, 0); + Test.AssertEquals(obj2.SpecialConstructionCount, 1); + Test.AssertEquals(obj2.DefaultConstrutorCallCount, 0); + Test.AssertEquals(obj2.SpecialConstrutorCallCount, 1); + Test.AssertEquals(obj2.MultiplyIntegerValue(21), 63); + + var internalObj = obj.InternalObject; + Test.Assert(ReferenceEquals(obj2, internalObj)); // Ensure it always use the same object instance + Test.AssertEquals(obj2.NativeConstructionCount, 1); // And that constructors are not called again + Test.AssertEquals(obj2.MultiplyIntegerValue(32), 96); // And that it is still usable + + obj.Dispose(); + obj2.Dispose(); + } +} + +} diff --git a/src/tests/efl_mono/dummy_constructible_object.c b/src/tests/efl_mono/dummy_constructible_object.c new file mode 100644 index 0000000000..870895066c --- /dev/null +++ b/src/tests/efl_mono/dummy_constructible_object.c @@ -0,0 +1,77 @@ +#include "libefl_mono_native_test.h" + +typedef struct _Dummy_Constructible_Object_Data +{ + Eo *internal_obj; + int native_construction_count; + int default_construction_count; + int special_construction_count; +} Dummy_Constructible_Object_Data; + + +EOLIAN static Eo * +_dummy_constructible_object_efl_object_constructor(Eo *obj, Dummy_Constructible_Object_Data *pd) +{ + ++(pd->native_construction_count); + return efl_constructor(efl_super(obj, DUMMY_CONSTRUCTIBLE_OBJECT_CLASS)); +} + +EOLIAN static void +_dummy_constructible_object_efl_object_destructor(Eo *obj, Dummy_Constructible_Object_Data *pd) +{ + if (pd->internal_obj) + efl_unref(pd->internal_obj); + efl_destructor(efl_super(obj, DUMMY_CONSTRUCTIBLE_OBJECT_CLASS)); +} + +EOLIAN static Efl_Object * +_dummy_constructible_object_construct_type_and_store(Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd, const Efl_Class *klass) +{ + pd->internal_obj = efl_add_ref(klass, NULL); + return pd->internal_obj; +} + +EOLIAN static void +_dummy_constructible_object_increment_default_construction_count(Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd) +{ + ++(pd->default_construction_count); +} + +EOLIAN static void +_dummy_constructible_object_increment_special_construction_count(Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd) +{ + ++(pd->special_construction_count); +} + +EOLIAN static int +_dummy_constructible_object_native_construction_count_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd) +{ + return pd->native_construction_count; +} + +EOLIAN static int +_dummy_constructible_object_default_construction_count_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd) +{ + return pd->default_construction_count; +} + +EOLIAN static int +_dummy_constructible_object_special_construction_count_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd) +{ + return pd->special_construction_count; +} + +EOLIAN static Efl_Object * +_dummy_constructible_object_internal_object_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd) +{ + return pd->internal_obj; +} + + +EOLIAN static int +_dummy_constructible_object_multiply_integer_value(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd, int v) +{ + return 2 * v; +} + +#include "dummy_constructible_object.eo.c" diff --git a/src/tests/efl_mono/dummy_constructible_object.eo b/src/tests/efl_mono/dummy_constructible_object.eo new file mode 100644 index 0000000000..ea508ed15c --- /dev/null +++ b/src/tests/efl_mono/dummy_constructible_object.eo @@ -0,0 +1,53 @@ +class Dummy.Constructible_Object extends Efl.Object { + methods { + construct_type_and_store { + params { + @in type: const(Efl.Class); + } + return: Efl.Object; + } + increment_default_construction_count { + } + increment_special_construction_count { + } + @property native_construction_count { + get { + } + values { + value: int; + } + } + @property default_construction_count { + get { + } + values { + value: int; + } + } + @property special_construction_count { + get { + } + values { + value: int; + } + } + @property internal_object { + get { + } + values { + value: Efl.Object; + } + } + multiply_integer_value @const { + params { + v: int; + } + return: int; + } + } + implements { + Efl.Object.constructor; + Efl.Object.destructor; + } +} + diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c index 4fdc69bbed..57d2a06ae6 100644 --- a/src/tests/efl_mono/dummy_test_object.c +++ b/src/tests/efl_mono/dummy_test_object.c @@ -59,9 +59,9 @@ Dummy_Numberwrapper **_new_obj_ref(int n) return &r; } -// ############ // -// Test.Testing // -// ############ // +// ################# // +// Dummy.Test_Object // +// ################# // static Efl_Object* _dummy_test_object_efl_object_constructor(Eo *obj, Dummy_Test_Object_Data *pd) diff --git a/src/tests/efl_mono/libefl_mono_native_test.h b/src/tests/efl_mono/libefl_mono_native_test.h index 9251118fc6..b726bd05c1 100644 --- a/src/tests/efl_mono/libefl_mono_native_test.h +++ b/src/tests/efl_mono/libefl_mono_native_test.h @@ -55,6 +55,7 @@ #include "dummy_inherit_helper.eo.h" #include "dummy_part_holder.eo.h" #include "dummy_event_manager.eo.h" +#include "dummy_constructible_object.eo.h" #include diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build index f75a5b8bb9..e464cdd2a8 100644 --- a/src/tests/efl_mono/meson.build +++ b/src/tests/efl_mono/meson.build @@ -7,6 +7,7 @@ eo_files = [ 'dummy_inherit_iface.eo', 'dummy_part_holder.eo', 'dummy_event_manager.eo', + 'dummy_constructible_object.eo', ] eo_file_targets = [] @@ -33,6 +34,7 @@ efl_mono_native_test = library('efl_mono_native_test', 'dummy_part_holder.c', 'dummy_test_object.c', 'dummy_event_manager.c', + 'dummy_constructible_object.c', ], dependencies : [ecore, eo, efl], ) @@ -65,6 +67,7 @@ efl_mono_src = [ 'Eldbus.cs', 'Eo.cs', 'EoPromises.cs', + 'EoConstruction.cs', 'Errors.cs', 'Events.cs', 'FunctionPointers.cs', From 4496022a3ca5223baceb11609d7659e1f34d6549 Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Fri, 28 Jun 2019 10:40:52 -0300 Subject: [PATCH 35/36] csharp: fix Eina_Stringshare support in containers for manual and generated API Summary: Both C strings and eina stringshares are bound as regular strings in EFL#, as working directly with these types would demand unnecessary hassle from the user viewpoint. But for eina containers this distinction is important, and since C# generics do not provide a convenient way of dealing with the same type requiring a different management based on some other condition (at least not without compromising the usability for other types), we added a simple `System.String` wrapper named `Eina.Stringshare` that works as a placeholder for signaling this distinction. Working with this class should be transparent in most use cases because it converts to and from `System.String` implicitly. It also implements equality/inequality methods for easier comparison with strings and other stringshare objects. Add new methods and a new container element trait for dealing specifically with `Eina_Stringshare` elements. Adapt eolian_mono to identify and generate the proper placeholder in methods that require stringshare containers. Remove some direct uses of DllImport-ed functions in favor of more flexible manual binding methods. Move `Eina.Stringshare` DllImport directives to a static class named `NativeMethods`, in accordance with the code design warning CA1060. Also add a TODO comment to move all other DllImport directives to this class. Change parameter of the method `Efl.Csharp.Application.OnInitialize` from `Eina.Array` to `string[]`. This will make this API more similar with the default C# way of receiving command line arguments. Add tests for containers storing stringshare elements. Reviewers: felipealmeida, lauromoura, segfaultxavi, bu5hm4n Reviewed By: lauromoura Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9178 --- .../eolian_mono/eolian/mono/marshall_type.hh | 34 +- .../eolian/mono/marshall_type_impl.hh | 47 +- .../eolian/mono/struct_definition.hh | 2 +- src/bin/eolian_mono/eolian/mono/type.hh | 38 +- src/bin/eolian_mono/eolian/mono/type_impl.hh | 5 +- .../mono/efl_mono/efl_csharp_application.cs | 16 +- src/bindings/mono/eina_mono/eina_common.cs | 43 +- .../mono/eina_mono/eina_container_common.cs | 153 ++++ src/bindings/mono/eina_mono/eina_hash.cs | 6 +- .../mono/eina_mono/eina_stringshare.cs | 220 ++++- src/bindings/mono/eo_mono/iwrapper.cs | 8 +- src/lib/efl_mono/efl_custom_exports_mono.c | 11 + src/tests/efl_mono/Eina.cs | 738 ++++++++++++++++ src/tests/efl_mono/EinaTestData.cs | 4 + src/tests/efl_mono/dummy_test_object.c | 788 +++++++++++++++++- src/tests/efl_mono/dummy_test_object.eo | 190 +++++ 16 files changed, 2260 insertions(+), 43 deletions(-) diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type.hh b/src/bin/eolian_mono/eolian/mono/marshall_type.hh index 5c350adebe..2b05e636c3 100644 --- a/src/bin/eolian_mono/eolian/mono/marshall_type.hh +++ b/src/bin/eolian_mono/eolian/mono/marshall_type.hh @@ -26,23 +26,41 @@ struct marshall_annotation_visitor_generate; */ struct marshall_type_generator { - marshall_type_generator(bool is_return = false) - : is_return(is_return) {} - + marshall_type_generator(bool is_return = false, bool is_special_subtype = false) + : is_return(is_return) + , is_special_subtype(is_special_subtype) + {} + template bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const { - return type.original_type.visit(detail::marshall_type_visitor_generate{sink, &context, type.c_type, false, is_return, type.is_ptr }); + return type.original_type.visit(detail::marshall_type_visitor_generate{ + sink + , &context + , type.c_type + , false + , is_return + , type.is_ptr + , is_special_subtype + }); } /* Some types may require a different conversion when they are in @out parameters. */ template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { - return param.type.original_type.visit(detail::marshall_type_visitor_generate{sink, &context, param.type.c_type - , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr}); + return param.type.original_type.visit(detail::marshall_type_visitor_generate{ + sink + , &context + , param.type.c_type + , param.direction != attributes::parameter_direction::in + , false + , param.type.is_ptr + , is_special_subtype + }); } bool is_return; + bool is_special_subtype; }; /* @@ -73,9 +91,9 @@ struct marshall_annotation_generator struct marshall_type_terminal { - marshall_type_generator const operator()(bool is_return) const + marshall_type_generator const operator()(bool is_return, bool is_special_subtype = false) const { - return marshall_type_generator(is_return); + return marshall_type_generator(is_return, is_special_subtype); } } const marshall_type = {}; diff --git a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh index b50c88f768..d3fcbfa41e 100644 --- a/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/marshall_type_impl.hh @@ -25,6 +25,7 @@ struct marshall_type_visitor_generate bool is_out; bool is_return; bool is_ptr; + bool is_special_subtype; typedef marshall_type_visitor_generate visitor_type; typedef bool result_type; @@ -70,12 +71,16 @@ struct marshall_type_visitor_generate { regular_type_def r = regular; r.base_qualifier.qualifier ^= qualifier_info::is_ref; + if (is_special_subtype) + return replace_base_type(r, "Eina.Stringshare"); return replace_base_type(r, "System.String"); }} , {"stringshare", false, [&] { regular_type_def r = regular; r.base_qualifier.qualifier ^= qualifier_info::is_ref; + if (is_special_subtype) + return replace_base_type(r, "Eina.Stringshare"); return replace_base_type(r, "System.String"); }} , {"strbuf", nullptr, [&] @@ -171,16 +176,40 @@ struct marshall_type_visitor_generate regular_type_def r = regular; r.base_type = "System.IntPtr"; r.namespaces.clear(); - return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(r); + return visitor_generate{ + sink + , context + , c_type + , is_out + , is_return + , is_ptr + , is_special_subtype + }(r); } else { - return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(regular); + return visitor_generate{ + sink + , context + , c_type + , is_out + , is_return + , is_ptr + , is_special_subtype + }(regular); } } bool operator()(attributes::klass_name klass_name) const { - return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(klass_name); + return visitor_generate{ + sink + , context + , c_type + , is_out + , is_return + , is_ptr + , is_special_subtype + }(klass_name); } bool operator()(attributes::complex_type_def const& complex) const { @@ -225,7 +254,7 @@ struct marshall_type_visitor_generate { regular_type_def no_pointer_regular = complex.outer; return visitor_type{sink, context, c_type, false}(no_pointer_regular) - && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context); + && as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context); }; if(eina::optional b = call_match @@ -250,7 +279,15 @@ struct marshall_type_visitor_generate return *b; } - return visitor_generate{sink, context, c_type, is_out, is_return, is_ptr}(complex); + return visitor_generate{ + sink + , context + , c_type + , is_out + , is_return + , is_ptr + , is_special_subtype + }(complex); } }; } } diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index 204484c2b0..851b9c4025 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -88,7 +88,7 @@ struct to_internal_field_convert_generator else if (regular && regular->base_type == "stringshare") { if (!as_generator( - indent << scope_tab << scope_tab << "_internal_struct." << string << " = Eina.Stringshare.eina_stringshare_add(_external_struct." << string << ");\n") + indent << scope_tab << scope_tab << "_internal_struct." << string << " = Eina.MemoryNative.AddStringshare(_external_struct." << string << ");\n") .generate(sink, std::make_tuple(field_name, field_name), context)) return false; } diff --git a/src/bin/eolian_mono/eolian/mono/type.hh b/src/bin/eolian_mono/eolian/mono/type.hh index f6a52853d0..cae2ad185f 100644 --- a/src/bin/eolian_mono/eolian/mono/type.hh +++ b/src/bin/eolian_mono/eolian/mono/type.hh @@ -14,29 +14,49 @@ struct visitor_generate; struct type_generator { - type_generator(bool is_return = false, bool is_optional = false) - : is_return(is_return), is_optional(is_optional) {} - + type_generator(bool is_return = false, bool is_optional = false, bool is_special_subtype = false) + : is_return(is_return) + , is_optional(is_optional) + , is_special_subtype(is_special_subtype) + {} + template bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const { - return type.original_type.visit(visitor_generate{sink, &context, type.c_type, false, is_return, type.is_ptr, is_optional}); + return type.original_type.visit(visitor_generate{ + sink + , &context + , type.c_type + , false + , is_return + , type.is_ptr + , is_optional + , is_special_subtype + }); } template bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const { - return param.type.original_type.visit(visitor_generate{sink, &context, param.type.c_type - , param.direction != attributes::parameter_direction::in, false, param.type.is_ptr, is_optional}); + return param.type.original_type.visit(visitor_generate{ + sink + , &context + , param.type.c_type + , param.direction != attributes::parameter_direction::in + , false + , param.type.is_ptr + , is_optional + , is_special_subtype + }); } - bool is_return, is_optional; + bool is_return, is_optional, is_special_subtype; }; struct type_terminal { - type_generator const operator()(bool is_return, bool is_optional = false) const + type_generator const operator()(bool is_return, bool is_optional = false, bool is_special_subtype = false) const { - return type_generator(is_return, is_optional); + return type_generator(is_return, is_optional, is_special_subtype); } } const type = {}; diff --git a/src/bin/eolian_mono/eolian/mono/type_impl.hh b/src/bin/eolian_mono/eolian/mono/type_impl.hh index 4b3f097dd4..8991247782 100644 --- a/src/bin/eolian_mono/eolian/mono/type_impl.hh +++ b/src/bin/eolian_mono/eolian/mono/type_impl.hh @@ -99,6 +99,7 @@ struct visitor_generate bool is_return; bool is_ptr; mutable bool is_optional; + bool is_special_subtype; typedef visitor_generate visitor_type; typedef bool result_type; @@ -205,6 +206,8 @@ struct visitor_generate { regular_type_def r = regular; r.base_qualifier.qualifier ^= qualifier_info::is_ref; + if (is_special_subtype) + return replace_base_type(r, "Eina.Stringshare"); return replace_base_type(r, "System.String"); }} , {"strbuf", nullptr, [&] @@ -400,7 +403,7 @@ struct visitor_generate // if(is_out) // pointers.push_back({{attributes::qualifier_info::is_none, {}}, true}); return visitor_type{sink, context, c_type, false}(no_pointer_regular) - && as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context) + && as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context) ; // && detail::generate_pointers(sink, pointers, *context, false); }; diff --git a/src/bindings/mono/efl_mono/efl_csharp_application.cs b/src/bindings/mono/efl_mono/efl_csharp_application.cs index ea29376c6c..4e3a2522cc 100644 --- a/src/bindings/mono/efl_mono/efl_csharp_application.cs +++ b/src/bindings/mono/efl_mono/efl_csharp_application.cs @@ -88,7 +88,7 @@ public abstract class Application /// /// Called when the application is started. Arguments from the command line are passed here. /// - protected abstract void OnInitialize(Eina.Array args); + protected abstract void OnInitialize(string[] args); /// /// Arguments are passed here, Additional calls to this function may occure, @@ -130,8 +130,8 @@ public abstract class Application { Init(components); Efl.App app = Efl.App.AppMain; - Eina.Array command_line = new Eina.Array(); - command_line.Append(Environment.GetCommandLineArgs()); + var command_line = new Eina.Array(); + command_line.Append(Array.ConvertAll(Environment.GetCommandLineArgs(), s => (Eina.Stringshare)s)); #if EFL_BETA app.SetCommandArray(command_line); #endif @@ -139,7 +139,15 @@ public abstract class Application { if (evt.arg.Initialization) { - OnInitialize(evt.arg.Argv); + var evtArgv = evt.arg.Argv; + int n = evtArgv.Length; + var argv = new string[n]; + for (int i = 0; i < n; ++i) + { + argv[i] = evtArgv[i]; + } + + OnInitialize(argv); } OnArguments(evt.arg); diff --git a/src/bindings/mono/eina_mono/eina_common.cs b/src/bindings/mono/eina_mono/eina_common.cs index 199b92bc06..029b08e820 100644 --- a/src/bindings/mono/eina_mono/eina_common.cs +++ b/src/bindings/mono/eina_mono/eina_common.cs @@ -75,6 +75,30 @@ public static class MemoryNative return NativeCustomExportFunctions.efl_mono_native_strdup(str); } + public static IntPtr AddStringshare(string str) + { + IntPtr nativeStr = StringConversion.ManagedStringToNativeUtf8Alloc(str); + try + { + var strShare = NativeMethods.eina_stringshare_add(nativeStr); + return strShare; + } + finally + { + Eina.MemoryNative.Free(nativeStr); + } + } + + public static void DelStringshare(IntPtr str) + { + NativeMethods.eina_stringshare_del(str); + } + + public static void DelStringshareRef(IntPtr ptr) + { + NativeMethods.efl_mono_native_stringshare_del_ref(ptr); + } + // IntPtr's for some native functions public static IntPtr PtrCompareFuncPtrGet() { @@ -91,6 +115,11 @@ public static class MemoryNative return NativeCustomExportFunctions.efl_mono_native_free_addr_get(); } + public static IntPtr StringshareDelFuncPtrGet() + { + return NativeMethods.efl_mono_native_stringshare_del_addr_get(); + } + public static IntPtr EflUnrefFuncPtrGet() { return NativeCustomExportFunctions.efl_mono_native_efl_unref_addr_get(); @@ -130,9 +159,17 @@ public static class StringConversion byte[] strbuf = Encoding.UTF8.GetBytes(managedString); IntPtr native = MemoryNative.Alloc(strbuf.Length + 1); - Marshal.Copy(strbuf, 0, native, strbuf.Length); - Marshal.WriteByte(native + strbuf.Length, 0); // write the terminating null - return native; + try + { + Marshal.Copy(strbuf, 0, native, strbuf.Length); + Marshal.WriteByte(native + strbuf.Length, 0); // write the terminating null + return native; + } + catch(Exception e) + { + MemoryNative.Free(native); + throw e; + } } public static string NativeUtf8ToManagedString(IntPtr pNativeData) diff --git a/src/bindings/mono/eina_mono/eina_container_common.cs b/src/bindings/mono/eina_mono/eina_container_common.cs index 7bc17d9215..603b0694ec 100644 --- a/src/bindings/mono/eina_mono/eina_container_common.cs +++ b/src/bindings/mono/eina_mono/eina_container_common.cs @@ -19,6 +19,7 @@ public enum ElementType { NumericType, StringType, + StringshareType, ObjectType }; @@ -195,6 +196,145 @@ public class StringElementTraits : IBaseElementTraits } } +public class StringshareElementTraits : IBaseElementTraits +{ + public StringshareElementTraits() + { + } + + public IntPtr ManagedToNativeAlloc(Eina.Stringshare man) + { + var strShare = MemoryNative.AddStringshare(man); + return strShare; + } + + public IntPtr ManagedToNativeAllocInlistNode(Eina.Stringshare man) + { + var node = new InlistNode(); + node.Val = ManagedToNativeAlloc(man); + GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned); + IntPtr ptr = pinnedData.AddrOfPinnedObject(); + IntPtr nat = MemoryNative.AllocCopy + (ptr, Marshal.SizeOf() + Marshal.SizeOf()); + pinnedData.Free(); + return nat; + } + + public void ManagedToNativeCopyTo(Eina.Stringshare man, IntPtr mem) + { + IntPtr stringptr = ManagedToNativeAlloc(man); + Marshal.WriteIntPtr(mem, stringptr); + } + + public void NativeFree(IntPtr nat) + { + if (nat != IntPtr.Zero) + { + MemoryNative.DelStringshare(nat); + } + } + + public void NativeFreeInlistNodeElement(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + return; + } + + var val = Marshal.PtrToStructure + (nat + Marshal.SizeOf()); + NativeFree(val); + } + + public void NativeFreeInlistNode(IntPtr nat, bool freeElement) + { + if (nat == IntPtr.Zero) + { + return; + } + + if (freeElement) + { + NativeFreeInlistNodeElement(nat); + } + + MemoryNative.Free(nat); + } + + public void NativeFreeInplace(IntPtr nat) + { + MemoryNative.DelStringshareRef(nat); + } + + public void ResidueFreeInplace(IntPtr nat) + { + } + + public Eina.Stringshare NativeToManaged(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + return default(Eina.Stringshare); + } + + return StringConversion.NativeUtf8ToManagedString(nat); + } + + public Eina.Stringshare NativeToManagedInlistNode(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + Eina.Log.Error("Null pointer for Inlist node."); + return default(Eina.Stringshare); + } + + IntPtr ptr_location = nat + Marshal.SizeOf(); + return NativeToManaged(Marshal.ReadIntPtr(ptr_location)); + } + + // Strings inplaced are always a pointer, because they are variable-sized + public Eina.Stringshare NativeToManagedInplace(IntPtr nat) + { + if (nat == IntPtr.Zero) + { + return default(Eina.Stringshare); + } + + nat = Marshal.ReadIntPtr(nat); + if (nat == IntPtr.Zero) + { + return default(Eina.Stringshare); + } + + return NativeToManaged(nat); + } + + public IntPtr EinaCompareCb() + { + return MemoryNative.StrCompareFuncPtrGet(); + } + + public IntPtr EinaFreeCb() + { + return MemoryNative.StringshareDelFuncPtrGet(); + } + + public IntPtr EinaHashNew() + { + return eina_hash_stringshared_new(MemoryNative.StringshareDelFuncPtrGet()); + } + + public IntPtr EinaInarrayNew(uint step) + { + return eina_inarray_new((uint)Marshal.SizeOf(), step); + } + + public IntPtr EinaHashIteratorKeyNew(IntPtr hash) + { + return eina_hash_iterator_key_new(hash); + } +} + public class EflObjectElementTraits : IBaseElementTraits { public IntPtr ManagedToNativeAlloc(T man) @@ -709,6 +849,11 @@ public static class TraitFunctions return type == typeof(string); } + public static bool IsStringshare(System.Type type) + { + return type == typeof(Eina.Stringshare); + } + public static Eina.ElementType GetElementTypeCode(System.Type type) { if (IsEflObject(type)) @@ -719,6 +864,10 @@ public static class TraitFunctions { return ElementType.StringType; } + else if (IsStringshare(type)) + { + return ElementType.StringshareType; + } else { return ElementType.NumericType; @@ -764,6 +913,10 @@ public static class TraitFunctions { traits = new StringElementTraits(); } + else if (IsStringshare(type)) + { + traits = new StringshareElementTraits(); + } else if (type.IsValueType) { if (type == typeof(int)) diff --git a/src/bindings/mono/eina_mono/eina_hash.cs b/src/bindings/mono/eina_mono/eina_hash.cs index 1617eba961..38522dc0e3 100644 --- a/src/bindings/mono/eina_mono/eina_hash.cs +++ b/src/bindings/mono/eina_mono/eina_hash.cs @@ -363,7 +363,9 @@ public class Hash : IEnumerable>, IDi private static bool ForceRefKey() { - return (!typeof(T).IsValueType) && (typeof(T) != typeof(string)); + return (!typeof(T).IsValueType) + && (typeof(T) != typeof(string)) + && (typeof(T) != typeof(Eina.Stringshare)); } private static IntPtr CopyNativeObject(T value, bool forceRef) @@ -439,7 +441,7 @@ public class Hash : IEnumerable>, IDi IntPtr old = eina_hash_set(Handle, nk, nv); FreeNativeIndirection(gchnk, ForceRefKey()); FreeNativeIndirection(gchnv, false); - if (OwnValue || old != IntPtr.Zero) + if (OwnValue && old != IntPtr.Zero) { NativeFree(old); } diff --git a/src/bindings/mono/eina_mono/eina_stringshare.cs b/src/bindings/mono/eina_mono/eina_stringshare.cs index 3b41bfbe3f..087db51bce 100644 --- a/src/bindings/mono/eina_mono/eina_stringshare.cs +++ b/src/bindings/mono/eina_mono/eina_stringshare.cs @@ -7,14 +7,224 @@ using System.Runtime.InteropServices; namespace Eina { -public class Stringshare +// TODO: move all native functions to a "NativeMethods" class +public static partial class NativeMethods { + [DllImport(efl.Libs.Eina)] public static extern IntPtr + eina_stringshare_add(IntPtr str); [DllImport(efl.Libs.Eina)] public static extern System.IntPtr - eina_stringshare_add_length(string str, System.UInt32 slen); - [DllImport(efl.Libs.Eina)] public static extern System.IntPtr - eina_stringshare_add(string str); + eina_stringshare_add_length(IntPtr str, UInt32 slen); [DllImport(efl.Libs.Eina)] public static extern void - eina_stringshare_del(System.IntPtr str); + eina_stringshare_del(IntPtr str); + [DllImport(efl.Libs.CustomExports)] public static extern void + efl_mono_native_stringshare_del_ref(IntPtr str); + [DllImport(efl.Libs.CustomExports)] public static extern IntPtr + efl_mono_native_stringshare_del_addr_get(); +} + +/// +/// Placeholder type to interact with the native type Eina_Stringshare, mainly for eina containers. +/// +/// +/// Using System.String and merely converting this type to it (by cast or implicitly) +/// is recommended for simplicity and ease of use. +/// +/// This type is just a System.String wrapper that works as a placeholder for +/// instrumentalizing proper interaction with native EFL API that demands +/// strings to be stringshares. +/// +/// Both C strings and eina stringshares are bound as regular strings in EFL#, +/// as working directly with these types would demand unnecessary hassle from +/// the user viewpoint. +/// But for eina containers this distinction is important, and since C# generics +/// do not provide a convenient way of dealing with the same type requiring +/// a different management based on some other condition (at least not without +/// compromising the usability for other types), we use this string wrapper +/// in order to signal this distinction. +/// +/// Implements equality/inequality methods for easier comparison with strings and +/// other Stringshare objects. For more specific operations convert to a string. +/// +public class Stringshare : IEquatable, IEquatable +{ + /// + /// Main constructor. Wrap the given string. + /// Have private acess to avoid wrapping a null reference, + /// use convertion or the factory method to create a new instance. + /// + /// + /// + private Stringshare(string s) + { + Str = s; + } + + /// + /// Auto-implemented property that holds the wrapped string value. + /// + public string Str { get; private set; } + + /// + /// Factory method to instantiate a new object. + /// Get a wrappper for the given string or a null reference if the given + /// string reference is also null. + /// + /// + /// + /// A new instance wrapping the given string, or a null reference if + /// the given string reference is also null. + /// + public static Stringshare Create(string s) + { + if (s == null) + { + return null; + } + + return new Stringshare(s); + } + + /// + /// Implicit convertion to string. + /// + public static implicit operator string(Stringshare ss) + { + if (ReferenceEquals(null, ss)) + { + return null; + } + + return ss.Str; + } + + /// + /// Implicit convertion from string to Stringshare. + /// + /// + /// Note that this method can be used to create an instance of this class, + /// either via an explicit cast or an implicit convertion. + /// + /// + public static implicit operator Stringshare(string s) + { + if (ReferenceEquals(null, s)) + { + return null; + } + + return new Stringshare(s); + } + + /// + /// Check two Stringshare objects for equality. + /// + /// + /// True if both wrapped strings have the same content or if both + /// references are null, false otherwise. + /// + public static bool operator==(Stringshare ss1, Stringshare ss2) + { + return ((string)ss1) == ((string)ss2); + } + + + /// + /// Check two Stringshare objects for inequality. + /// + /// + /// True if the wrapped strings have different content or if one reference is null + /// and the other is not, false otherwise. + /// + public static bool operator!=(Stringshare ss1, Stringshare ss2) + { + return !(ss1 == ss2); + } + + /// + /// Returns the wrapped string. + /// + /// + /// + /// The wrapped string. Same as the property Str. + public override string ToString() + { + return Str; + } + + /// + /// Override of GetHashCode for consistency with user-defined equality methods. + /// + /// + /// The wrapped string hash code. + /// + public override int GetHashCode() + { + return Str.GetHashCode(); + } + + /// + /// Check the given object for equality. + /// + /// + /// True if the given object is the same object or if it is another Stringshare object + /// and both wrapped strings are equal or if it is a string object and its content + /// is the same of the wrapped string. + /// In any other case it returns false. + /// + public override bool Equals(object other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() == typeof(string)) + { + return this.Str == (string)other; + } + + return other.GetType() == typeof(Stringshare) && this == ((Stringshare)other); + } + + /// + /// Check the given Stringshare for equality. + /// + /// + /// True if the given Stringshare object is not null and its wrapped string + /// have the same content of this.Str, false otherwise. + /// + public bool Equals(Stringshare other) + { + return this == other; + } + + /// + /// Check the given Stringshare for equality. + /// + /// + /// True if the given string is not null and the wrapped string have the same + /// content of the given string, false otherwise. + /// + public bool Equals(string other) + { + return this.Str == other; + } + + /// + /// Get the wrapped string. + /// + /// + /// + /// The wrapped string. Same as the property Str. + public string Get() + { + return Str; + } } } diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs index 966759b314..caf28a700f 100644 --- a/src/bindings/mono/eo_mono/iwrapper.cs +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -494,7 +494,7 @@ public class Globals { foreach (IntPtr ptr in dict.Values) { - Eina.Stringshare.eina_stringshare_del(ptr); + Eina.NativeMethods.eina_stringshare_del(ptr); } } @@ -1148,13 +1148,13 @@ public class StringsharePassOwnershipMarshaler : ICustomMarshaler public object MarshalNativeToManaged(IntPtr pNativeData) { var ret = Eina.StringConversion.NativeUtf8ToManagedString(pNativeData); - Eina.Stringshare.eina_stringshare_del(pNativeData); + Eina.NativeMethods.eina_stringshare_del(pNativeData); return ret; } public IntPtr MarshalManagedToNative(object managedObj) { - return Eina.Stringshare.eina_stringshare_add((string)managedObj); + return Eina.MemoryNative.AddStringshare((string)managedObj); } public void CleanUpNativeData(IntPtr pNativeData) @@ -1193,7 +1193,7 @@ public class StringshareKeepOwnershipMarshaler : ICustomMarshaler public IntPtr MarshalManagedToNative(object managedObj) { - return Eina.Stringshare.eina_stringshare_add((string)managedObj); + return Eina.MemoryNative.AddStringshare((string)managedObj); } public void CleanUpNativeData(IntPtr pNativeData) diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c index 8d57ad730f..aa2572f49d 100644 --- a/src/lib/efl_mono/efl_custom_exports_mono.c +++ b/src/lib/efl_mono/efl_custom_exports_mono.c @@ -125,6 +125,12 @@ EAPI void efl_mono_native_free_ref(void **ptr) free(*ptr); } +EAPI void efl_mono_native_stringshare_del_ref(void **str) +{ + if (!str) return; + eina_stringshare_del(*str); +} + EAPI void *efl_mono_native_alloc_copy(const void *val, unsigned int size) { if (!val) return NULL; @@ -161,6 +167,11 @@ EAPI Eina_Free_Cb efl_mono_native_free_addr_get() return (Eina_Free_Cb)free; } +EAPI Eina_Free_Cb efl_mono_native_stringshare_del_addr_get() +{ + return (Eina_Free_Cb)eina_stringshare_del; +} + EAPI Eina_Free_Cb efl_mono_native_efl_unref_addr_get() { return (Eina_Free_Cb)efl_mono_thread_safe_efl_unref; diff --git a/src/tests/efl_mono/Eina.cs b/src/tests/efl_mono/Eina.cs index c15e062002..90e8586d93 100644 --- a/src/tests/efl_mono/Eina.cs +++ b/src/tests/efl_mono/Eina.cs @@ -492,6 +492,14 @@ class TestEinaArray Test.AssertEquals("test string §éΨبÿツ", a[0]); } + public static void push_stringshare() + { + var a = new Eina.Array(); + Test.Assert(a.Handle != IntPtr.Zero); + Test.Assert(a.Push("test string §éΨبÿツ")); + Test.AssertEquals("test string §éΨبÿツ", a[0].Str); + } + public static void push_obj() { var a = new Eina.Array(); @@ -521,6 +529,15 @@ class TestEinaArray Test.Assert(a.Count() == 0); } + public static void pop_stringshare() + { + var a = new Eina.Array(); + Test.Assert(a.Handle != IntPtr.Zero); + Test.Assert(a.Push("test string")); + Test.Assert(a.Pop() == "test string"); + Test.Assert(a.Count() == 0); + } + public static void pop_obj() { var a = new Eina.Array(); @@ -558,6 +575,18 @@ class TestEinaArray Test.Assert(a[0] == "abc"); } + public static void data_set_stringshare() + { + var a = new Eina.Array(); + Test.Assert(a.Handle != IntPtr.Zero); + Test.Assert(a.Push("test string")); + Test.Assert(a[0] == "test string"); + a.DataSet(0, "other string"); + Test.Assert(a[0] == "other string"); + a[0] = "abc"; + Test.Assert(a[0] == "abc"); + } + public static void data_set_obj() { var a = new Eina.Array(); @@ -617,6 +646,22 @@ class TestEinaArray Test.Assert(a.Count() == 3); } + public static void count_stringshare() + { + var a = new Eina.Array(); + Test.Assert(a.Handle != IntPtr.Zero); + Test.Assert(a.Count() == 0); + Test.Assert(a.Push("a")); + Test.Assert(a[0] == "a"); + Test.Assert(a.Count() == 1); + Test.Assert(a.Push("b")); + Test.Assert(a[1] == "b"); + Test.Assert(a.Count() == 2); + Test.Assert(a.Push("c")); + Test.Assert(a[2] == "c"); + Test.Assert(a.Count() == 3); + } + public static void count_obj() { var a = new Eina.Array(); @@ -678,6 +723,22 @@ class TestEinaArray Test.Assert(a.Length == 3); } + public static void length_stringshare() + { + var a = new Eina.Array(); + Test.Assert(a.Handle != IntPtr.Zero); + Test.Assert(a.Length == 0); + Test.Assert(a.Push("a")); + Test.Assert(a[0] == "a"); + Test.Assert(a.Length == 1); + Test.Assert(a.Push("b")); + Test.Assert(a[1] == "b"); + Test.Assert(a.Length == 2); + Test.Assert(a.Push("c")); + Test.Assert(a[2] == "c"); + Test.Assert(a.Length == 3); + } + public static void eina_array_as_ienumerable_int() { var a = new Eina.Array(); @@ -710,6 +771,22 @@ class TestEinaArray } } + public static void eina_array_as_ienumerable_stringshare() + { + var a = new Eina.Array(); + Test.Assert(a.Handle != IntPtr.Zero); + Test.Assert(a.Push("X")); + Test.Assert(a.Push("XX")); + Test.Assert(a.Push("XXX")); + + string cmp = "X"; + foreach (string e in a) + { + Test.AssertEquals(cmp, e); + cmp = cmp + "X"; + } + } + public static void eina_array_as_ienumerable_obj() { var a = new Dummy.Numberwrapper(); @@ -888,6 +965,80 @@ class TestEinaArray Test.Assert(arr.Handle == IntPtr.Zero); } + // Eina.Stringshare // + public static void test_eina_array_strshare_in() + { + var t = new Dummy.TestObject(); + var arr = new Eina.Array(); + arr.Append(base_seq_strshare); + Test.Assert(t.EinaArrayStrshareIn(arr)); + Test.Assert(arr.Own); + Test.Assert(arr.ToArray().SequenceEqual(modified_seq_strshare)); + arr.Dispose(); + Test.Assert(arr.Handle == IntPtr.Zero); + } + + public static void test_eina_array_strshare_in_own() + { + var t = new Dummy.TestObject(); + var arr = new Eina.Array(); + arr.Append(base_seq_strshare); + Test.Assert(t.EinaArrayStrshareInOwn(arr)); + Test.Assert(!arr.Own); + Test.Assert(arr.ToArray().SequenceEqual(modified_seq_strshare)); + arr.Dispose(); + Test.Assert(arr.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaArrayStrshareInOwn()); + } + + public static void test_eina_array_strshare_out() + { + var t = new Dummy.TestObject(); + Eina.Array arr; + Test.Assert(t.EinaArrayStrshareOut(out arr)); + Test.Assert(!arr.Own); + Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare)); + Test.Assert(arr.Append(append_seq_strshare)); + arr.Dispose(); + Test.Assert(arr.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaArrayStrshareOut()); + } + + public static void test_eina_array_strshare_out_own() + { + var t = new Dummy.TestObject(); + Eina.Array arr; + Test.Assert(t.EinaArrayStrshareOutOwn(out arr)); + Test.Assert(arr.Own); + Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare)); + Test.Assert(arr.Append(append_seq_strshare)); + arr.Dispose(); + Test.Assert(arr.Handle == IntPtr.Zero); + } + + public static void test_eina_array_strshare_return() + { + var t = new Dummy.TestObject(); + var arr = t.EinaArrayStrshareReturn(); + Test.Assert(!arr.Own); + Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare)); + Test.Assert(arr.Append(append_seq_strshare)); + arr.Dispose(); + Test.Assert(arr.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaArrayStrshareReturn()); + } + + public static void test_eina_array_strshare_return_own() + { + var t = new Dummy.TestObject(); + var arr = t.EinaArrayStrshareReturnOwn(); + Test.Assert(arr.Own); + Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare)); + Test.Assert(arr.Append(append_seq_strshare)); + arr.Dispose(); + Test.Assert(arr.Handle == IntPtr.Zero); + } + // Object // public static void test_eina_array_obj_in() @@ -1315,6 +1466,17 @@ class TestEinaList Test.Assert(lst[0] == "abc"); } + public static void data_set_stringshare() + { + var lst = new Eina.List(); + lst.Append("test string"); + Test.Assert(lst[0] == "test string"); + lst.DataSet(0, "other string"); + Test.Assert(lst[0] == "other string"); + lst[0] = "abc"; + Test.Assert(lst[0] == "abc"); + } + public static void data_set_obj() { var lst = new Eina.List(); @@ -1371,6 +1533,21 @@ class TestEinaList Test.Assert(lst.Count() == 3); } + public static void append_count_stringshare() + { + var lst = new Eina.List(); + Test.Assert(lst.Count() == 0); + lst.Append("a"); + Test.Assert(lst[0] == "a"); + Test.Assert(lst.Count() == 1); + lst.Append("b"); + Test.Assert(lst[1] == "b"); + Test.Assert(lst.Count() == 2); + lst.Append("c"); + Test.Assert(lst[2] == "c"); + Test.Assert(lst.Count() == 3); + } + public static void append_count_obj() { var lst = new Eina.List(); @@ -1429,6 +1606,21 @@ class TestEinaList Test.Assert(lst.Length == 3); } + public static void length_stringshare() + { + var lst = new Eina.List(); + Test.Assert(lst.Length == 0); + lst.Append("a"); + Test.Assert(lst[0] == "a"); + Test.Assert(lst.Length == 1); + lst.Append("b"); + Test.Assert(lst[1] == "b"); + Test.Assert(lst.Length == 2); + lst.Append("c"); + Test.Assert(lst[2] == "c"); + Test.Assert(lst.Length == 3); + } + public static void prepend_count_int() { var lst = new Eina.List(); @@ -1459,6 +1651,21 @@ class TestEinaList Test.Assert(lst.Count() == 3); } + public static void prepend_count_stringshare() + { + var lst = new Eina.List(); + Test.Assert(lst.Count() == 0); + lst.Prepend("a"); + Test.Assert(lst[0] == "a"); + Test.Assert(lst.Count() == 1); + lst.Prepend("b"); + Test.Assert(lst[0] == "b"); + Test.Assert(lst.Count() == 2); + lst.Prepend("c"); + Test.Assert(lst[0] == "c"); + Test.Assert(lst.Count() == 3); + } + public static void prepend_count_obj() { var lst = new Eina.List(); @@ -1511,6 +1718,18 @@ class TestEinaList } + public static void sorted_insert_stringshare() + { + var lst = new Eina.List(); + lst.SortedInsert("c"); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"c"})); + lst.SortedInsert("a"); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"a","c"})); + lst.SortedInsert("b"); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"a","b","c"})); + + } + public static void sort_int() { var lst = new Eina.List(); @@ -1536,6 +1755,18 @@ class TestEinaList Test.Assert(lst.ToArray().SequenceEqual(new string[]{"a","b","c","d"})); } + public static void sort_stringshare() + { + var lst = new Eina.List(); + lst.Append("d"); + lst.Append("b"); + lst.Append("a"); + lst.Append("c"); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"d","b","a","c"})); + lst.Sort(); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"a","b","c","d"})); + } + public static void reverse_int() { var lst = new Eina.List(); @@ -1559,6 +1790,17 @@ class TestEinaList Test.Assert(lst.ToArray().SequenceEqual(new string[]{"c","b","a"})); } + public static void reverse_stringshare() + { + var lst = new Eina.List(); + lst.Append("a"); + lst.Append("b"); + lst.Append("c"); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"a","b","c"})); + lst.Reverse(); + Test.Assert(lst.ToArray().SequenceEqual(new Eina.Stringshare[]{"c","b","a"})); + } + public static void eina_list_as_ienumerable_int() { var lst = new Eina.List(); @@ -1589,6 +1831,21 @@ class TestEinaList } } + public static void eina_list_as_ienumerable_stringshare() + { + var lst = new Eina.List(); + lst.Append("X"); + lst.Append("XX"); + lst.Append("XXX"); + + string cmp = "X"; + foreach (string e in lst) + { + Test.AssertEquals(cmp, e); + cmp = cmp + "X"; + } + } + public static void eina_list_as_ienumerable_obj() { var a = new Dummy.Numberwrapper(); @@ -1760,6 +2017,77 @@ class TestEinaList Test.Assert(lst.Handle == IntPtr.Zero); } + // Eina.Stringshare // + public static void test_eina_list_strshare_in() + { + var t = new Dummy.TestObject(); + var lst = new Eina.List(); + lst.AppendArray(base_seq_strshare); + Test.Assert(t.EinaListStrshareIn(lst)); + Test.Assert(lst.Own); + Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); + lst.Dispose(); + Test.Assert(lst.Handle == IntPtr.Zero); + } + + public static void test_eina_list_strshare_in_own() + { + var t = new Dummy.TestObject(); + var lst = new Eina.List(); + lst.AppendArray(base_seq_strshare); + Test.Assert(t.EinaListStrshareInOwn(lst)); + Test.Assert(!lst.Own); + lst.Dispose(); + Test.Assert(lst.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaListStrshareInOwn()); + } + + public static void test_eina_list_strshare_out() + { + var t = new Dummy.TestObject(); + Eina.List lst; + Test.Assert(t.EinaListStrshareOut(out lst)); + Test.Assert(!lst.Own); + Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); + lst.Dispose(); + Test.Assert(lst.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaListStrshareOut()); + } + + public static void test_eina_list_strshare_out_own() + { + var t = new Dummy.TestObject(); + Eina.List lst; + Test.Assert(t.EinaListStrshareOutOwn(out lst)); + Test.Assert(lst.Own); + Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); + lst.AppendArray(append_seq_strshare); + lst.Dispose(); + Test.Assert(lst.Handle == IntPtr.Zero); + } + + public static void test_eina_list_strshare_return() + { + var t = new Dummy.TestObject(); + var lst = t.EinaListStrshareReturn(); + Test.Assert(!lst.Own); + Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); + lst.Dispose(); + Test.Assert(lst.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaListStrshareReturn()); + } + + public static void test_eina_list_strshare_return_own() + { + var t = new Dummy.TestObject(); + var lst = t.EinaListStrshareReturnOwn(); + Test.Assert(lst.Own); + Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare)); + lst.AppendArray(append_seq_strshare); + lst.Dispose(); + Test.Assert(lst.Handle == IntPtr.Zero); + } + // Object // public static void test_eina_list_obj_in() @@ -2149,6 +2477,26 @@ class TestEinaHash hsh.Dispose(); } + public static void data_set_strshare() + { + var hsh = new Eina.Hash(); + Test.Assert(hsh.Count == 0); + + hsh["aa"] = "aaa"; + Test.Assert(hsh["aa"] == "aaa"); + Test.Assert(hsh.Count == 1); + + hsh["bb"] = "bbb"; + Test.Assert(hsh["bb"] == "bbb"); + Test.Assert(hsh.Count == 2); + + hsh["cc"] = "ccc"; + Test.Assert(hsh["cc"] == "ccc"); + Test.Assert(hsh.Count == 3); + + hsh.Dispose(); + } + public static void data_set_obj() { var hsh = new Eina.Hash(); @@ -2236,6 +2584,34 @@ class TestEinaHash hsh.Dispose(); } + public static void eina_hash_as_ienumerable_strshare() + { + var hsh = new Eina.Hash(); + var dct = new Dictionary(); + + hsh["aa"] = "aaa"; + hsh["bb"] = "bbb"; + hsh["cc"] = "ccc"; + + dct["aa"] = "aaa"; + dct["bb"] = "bbb"; + dct["cc"] = "ccc"; + + int count = 0; + + foreach (KeyValuePair kvp in hsh) + { + Test.Assert(dct[kvp.Key] == kvp.Value); + dct.Remove(kvp.Key); + ++count; + } + + Test.AssertEquals(count, 3); + Test.AssertEquals(dct.Count, 0); + + hsh.Dispose(); + } + public static void eina_hash_as_ienumerable_obj() { var hsh = new Eina.Hash(); @@ -2444,6 +2820,90 @@ class TestEinaHash Test.Assert(t.CheckEinaHashStrReturnOwn()); } + // Eina.Stringshare // + + /*public static void test_eina_hash_strshare_in() + { + var t = new Dummy.TestObject(); + var hsh = new Eina.Hash(); + hsh["aa"] = "aaa"; + Test.Assert(t.EinaHashStrshareIn(hsh)); + Test.Assert(hsh.Own); + Test.Assert(hsh["aa"] == "aaa"); + Test.Assert(hsh["bb"] == "bbb"); + hsh.Dispose(); + Test.Assert(hsh.Handle == IntPtr.Zero); + } + + public static void test_eina_hash_strshare_in_own() + { + var t = new Dummy.TestObject(); + var hsh = new Eina.Hash(); + hsh["aa"] = "aaa"; + Test.Assert(t.EinaHashStrshareInOwn(hsh)); + Test.Assert(!hsh.Own); + Test.Assert(hsh["aa"] == "aaa"); + Test.Assert(hsh["bb"] == "bbb"); + hsh["cc"] = "ccc"; + hsh.Dispose(); + Test.Assert(hsh.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaHashStrshareInOwn()); + } + + public static void test_eina_hash_strshare_out() + { + var t = new Dummy.TestObject(); + Eina.Hash hsh; + Test.Assert(t.EinaHashStrshareOut(out hsh)); + Test.Assert(!hsh.Own); + Test.Assert(hsh["aa"] == "aaa"); + hsh["bb"] = "bbb"; + Test.Assert(hsh["bb"] == "bbb"); + hsh.Dispose(); + Test.Assert(hsh.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaHashStrshareOut()); + } + + public static void test_eina_hash_strshare_out_own() + { + var t = new Dummy.TestObject(); + Eina.Hash hsh; + Test.Assert(t.EinaHashStrshareOutOwn(out hsh)); + Test.Assert(hsh.Own); + Test.Assert(hsh["aa"] == "aaa"); + hsh["bb"] = "bbb"; + Test.Assert(hsh["bb"] == "bbb"); + hsh.Dispose(); + Test.Assert(hsh.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaHashStrshareOutOwn()); + } + + public static void test_eina_hash_strshare_return() + { + var t = new Dummy.TestObject(); + var hsh = t.EinaHashStrshareReturn(); + Test.Assert(!hsh.Own); + Test.Assert(hsh["aa"] == "aaa"); + hsh["bb"] = "bbb"; + Test.Assert(hsh["bb"] == "bbb"); + hsh.Dispose(); + Test.Assert(hsh.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaHashStrshareReturn()); + } + + public static void test_eina_hash_strshare_return_own() + { + var t = new Dummy.TestObject(); + var hsh = t.EinaHashStrshareReturnOwn(); + Test.Assert(hsh.Own); + Test.Assert(hsh["aa"] == "aaa"); + hsh["bb"] = "bbb"; + Test.Assert(hsh["bb"] == "bbb"); + hsh.Dispose(); + Test.Assert(hsh.Handle == IntPtr.Zero); + Test.Assert(t.CheckEinaHashStrshareReturnOwn()); + }*/ + // Object // public static void test_eina_hash_obj_in() @@ -2643,6 +3103,38 @@ class TestEinaIterator arr.Dispose(); } + public static void eina_array_strshare_empty_iterator() + { + var arr = new Eina.Array(); + var itr = arr.GetIterator(); + int idx = 0; + foreach (string e in itr) + { + ++idx; + } + Test.AssertEquals(idx, 0); + + itr.Dispose(); + arr.Dispose(); + } + + public static void eina_array_strshare_filled_iterator() + { + var arr = new Eina.Array(); + arr.Append(base_seq_strshare); + var itr = arr.GetIterator(); + int idx = 0; + foreach (string e in itr) + { + Test.Assert(e == base_seq_strshare[idx]); + ++idx; + } + Test.AssertEquals(idx, base_seq_strshare.Length); + + itr.Dispose(); + arr.Dispose(); + } + public static void eina_array_obj_empty_iterator() { var arr = new Eina.Array(); @@ -2777,6 +3269,38 @@ class TestEinaIterator lst.Dispose(); } + public static void eina_list_strshare_empty_iterator() + { + var lst = new Eina.List(); + var itr = lst.GetIterator(); + int idx = 0; + foreach (string e in itr) + { + ++idx; + } + Test.AssertEquals(idx, 0); + + itr.Dispose(); + lst.Dispose(); + } + + public static void eina_list_strshare_filled_iterator() + { + var lst = new Eina.List(); + lst.AppendArray(base_seq_strshare); + var itr = lst.GetIterator(); + int idx = 0; + foreach (string e in itr) + { + Test.Assert(e == base_seq_strshare[idx]); + ++idx; + } + Test.AssertEquals(idx, base_seq_strshare.Length); + + itr.Dispose(); + lst.Dispose(); + } + public static void eina_list_obj_empty_iterator() { var lst = new Eina.List(); @@ -3015,6 +3539,92 @@ class TestEinaIterator hsh.Dispose(); } +/* + public static void eina_hash_keys_strshare_empty_iterator() + { + var hsh = new Eina.Hash(); + var itr = hsh.Keys(); + bool entered = false; + foreach (string e in itr) + { + entered = true; + } + Test.Assert(!entered); + + itr.Dispose(); + hsh.Dispose(); + } + + public static void eina_hash_values_strshare_empty_iterator() + { + var hsh = new Eina.Hash(); + var itr = hsh.Values(); + bool entered = false; + foreach (string e in itr) + { + entered = true; + } + Test.Assert(!entered); + + itr.Dispose(); + hsh.Dispose(); + } + + public static void eina_hash_keys_strshare_filled_iterator() + { + var hsh = new Eina.Hash(); + var dct = new Dictionary(); + hsh["aa"] = "aaa"; + hsh["bb"] = "bbb"; + hsh["cc"] = "ccc"; + dct["aa"] = true; + dct["bb"] = true; + dct["cc"] = true; + + var itr = hsh.Keys(); + + int idx = 0; + foreach (string e in itr) + { + Test.Assert(dct[e]); + dct.Remove(e); + ++idx; + } + Test.AssertEquals(dct.Count, 0); + Test.AssertEquals(idx, 3); + + itr.Dispose(); + hsh.Dispose(); + } + + public static void eina_hash_values_strshare_filled_iterator() + { + var hsh = new Eina.Hash(); + var dct = new Dictionary(); + hsh["aa"] = "aaa"; + hsh["bb"] = "bbb"; + hsh["cc"] = "ccc"; + dct["aaa"] = true; + dct["bbb"] = true; + dct["ccc"] = true; + + var itr = hsh.Values(); + + int idx = 0; + foreach (string e in itr) + { + Test.Assert(dct[e]); + dct.Remove(e); + ++idx; + } + Test.AssertEquals(dct.Count, 0); + Test.AssertEquals(idx, 3); + + itr.Dispose(); + hsh.Dispose(); + } +*/ + public static void eina_hash_keys_obj_empty_iterator() { var hsh = new Eina.Hash(); @@ -3377,6 +3987,134 @@ class TestEinaIterator itr.Dispose(); } + // Eina.Stringshare // + + public static void test_eina_iterator_strshare_in() + { + var t = new Dummy.TestObject(); + var arr = new Eina.Array(); + arr.Append(base_seq_strshare); + var itr = arr.GetIterator(); + + Test.Assert(itr.Own); + Test.Assert(arr.Own); + Test.Assert(arr.OwnContent); + + Test.Assert(t.EinaIteratorStrshareIn(itr)); + + Test.Assert(itr.Own); + Test.Assert(arr.Own); + Test.Assert(arr.OwnContent); + + itr.Dispose(); + arr.Dispose(); + } + + public static void test_eina_iterator_strshare_in_own() + { + var t = new Dummy.TestObject(); + var arr = new Eina.Array(); + arr.Append(base_seq_strshare); + var itr = arr.GetIterator(); + + Test.Assert(itr.Own); + Test.Assert(arr.Own); + Test.Assert(arr.OwnContent); + + Test.Assert(t.EinaIteratorStrshareInOwn(itr)); + + Test.Assert(!itr.Own); + Test.Assert(arr.Own); + Test.Assert(arr.OwnContent); + + itr.Dispose(); + arr.Dispose(); + + Test.Assert(t.CheckEinaIteratorStrshareInOwn()); + } + + public static void test_eina_iterator_strshare_out() + { + var t = new Dummy.TestObject(); + Eina.Iterator itr; + + Test.Assert(t.EinaIteratorStrshareOut(out itr)); + + Test.Assert(!itr.Own); + + int idx = 0; + foreach (Eina.Stringshare e in itr) + { + Test.AssertEquals(e, base_seq_strshare[idx]); + ++idx; + } + Test.AssertEquals(idx, base_seq_strshare.Length); + + itr.Dispose(); + + Test.Assert(t.CheckEinaIteratorStrshareOut()); + } + + public static void test_eina_iterator_strshare_out_own() + { + var t = new Dummy.TestObject(); + Eina.Iterator itr; + + Test.Assert(t.EinaIteratorStrshareOutOwn(out itr)); + + Test.Assert(itr.Own); + + int idx = 0; + foreach (Eina.Stringshare e in itr) + { + Test.AssertEquals(e, base_seq_strshare[idx]); + ++idx; + } + Test.AssertEquals(idx, base_seq_strshare.Length); + + itr.Dispose(); + } + + public static void test_eina_iterator_strshare_return() + { + var t = new Dummy.TestObject(); + + var itr = t.EinaIteratorStrshareReturn(); + + Test.Assert(!itr.Own); + + int idx = 0; + foreach (Eina.Stringshare e in itr) + { + Test.AssertEquals(e, base_seq_strshare[idx]); + ++idx; + } + Test.AssertEquals(idx, base_seq_strshare.Length); + + itr.Dispose(); + + Test.Assert(t.CheckEinaIteratorStrshareReturn()); + } + + public static void test_eina_iterator_strshare_return_own() + { + var t = new Dummy.TestObject(); + + var itr = t.EinaIteratorStrshareReturnOwn(); + + Test.Assert(itr.Own); + + int idx = 0; + foreach (Eina.Stringshare e in itr) + { + Test.AssertEquals(e, base_seq_strshare[idx]); + ++idx; + } + Test.AssertEquals(idx, base_seq_strshare.Length); + + itr.Dispose(); + } + // Object // public static void test_eina_iterator_obj_in() diff --git a/src/tests/efl_mono/EinaTestData.cs b/src/tests/efl_mono/EinaTestData.cs index c4272a8ca2..b64040d5eb 100644 --- a/src/tests/efl_mono/EinaTestData.cs +++ b/src/tests/efl_mono/EinaTestData.cs @@ -24,6 +24,10 @@ public static class BaseData public static readonly string[] append_seq_str = {"42","43","33"}; public static readonly string[] modified_seq_str = {"0x0","0x2A","0x42","42","43","33"}; + public static readonly Eina.Stringshare[] base_seq_strshare = {"0x0","0x2A","0x42"}; + public static readonly Eina.Stringshare[] append_seq_strshare = {"42","43","33"}; + public static readonly Eina.Stringshare[] modified_seq_strshare = {"0x0","0x2A","0x42","42","43","33"}; + public static Dummy.Numberwrapper NW(int n) { var nw = new Dummy.Numberwrapper(); diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c index 57d2a06ae6..93eaeb084d 100644 --- a/src/tests/efl_mono/dummy_test_object.c +++ b/src/tests/efl_mono/dummy_test_object.c @@ -19,6 +19,7 @@ typedef struct Dummy_Test_Object_Data // Containers passed to C# as iterator/accessors Eina_Array *out_array; + Eina_Free_Cb out_array_free_element_cb; } Dummy_Test_Object_Data; static @@ -101,7 +102,15 @@ _dummy_test_object_efl_object_destructor(Eo *obj, Dummy_Test_Object_Data *pd) } if (pd->out_array) - eina_array_free(pd->out_array); + { + if (pd->out_array_free_element_cb) + { + unsigned n = eina_array_count(pd->out_array); + for (unsigned i = 0; i < n; ++i) + pd->out_array_free_element_cb(eina_array_data_get(pd->out_array, i)); + } + eina_array_free(pd->out_array); + } efl_destructor(efl_super(obj, DUMMY_TEST_OBJECT_CLASS)); } @@ -728,6 +737,139 @@ Eina_Array *_dummy_test_object_eina_array_str_return_own(EINA_UNUSED Eo *obj, EI return arr; } +// Eina_Stringshare + +Eina_Bool _array_strshare_equal(const Eina_Array *arr, const char * const base[], unsigned int len) +{ + Eina_Bool result = EINA_TRUE; + if (eina_array_count(arr) != len) + return EINA_FALSE; + for (unsigned int i = 0; i < len && result; ++i) + { + Eina_Stringshare *ssa = eina_array_data_get(arr, i); + Eina_Stringshare *sse = eina_stringshare_add(base[i]); + result = (ssa == sse); + if (!result) + fprintf(stderr, "Unexpected stringshare value. Expected: \"%s\" [%p]; Actual: \"%s\" [%p].\n", sse, sse, ssa, ssa); + eina_stringshare_del(sse); + } + return result; +} + +Eina_Bool _dummy_test_object_eina_array_strshare_in(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Array *arr) +{ + Eina_Bool r = _array_strshare_equal(arr, base_seq_str, base_seq_str_size); + eina_array_push(arr, eina_stringshare_add("42")); + eina_array_push(arr, eina_stringshare_add("43")); + eina_array_push(arr, eina_stringshare_add("33")); + return r; +} + +static Eina_Array *_array_strshare_in_own_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_array_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Array *arr) +{ + Eina_Bool r = _array_strshare_equal(arr, base_seq_str, base_seq_str_size); + eina_array_push(arr, eina_stringshare_add("42")); + eina_array_push(arr, eina_stringshare_add("43")); + eina_array_push(arr, eina_stringshare_add("33")); + _array_strshare_in_own_to_check = arr; + return r; +} + +Eina_Bool _dummy_test_object_check_eina_array_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_array_strshare_in_own_to_check) return EINA_FALSE; + + Eina_Bool r = _array_strshare_equal(_array_strshare_in_own_to_check, modified_seq_str, modified_seq_str_size); + + unsigned int i; + Eina_Stringshare *ele; + Eina_Array_Iterator it; + EINA_ARRAY_ITER_NEXT(_array_strshare_in_own_to_check, i, ele, it) + eina_stringshare_del(ele); + + eina_array_free(_array_strshare_in_own_to_check); + _array_strshare_in_own_to_check = NULL; + return r; +} + +Eina_Array *_array_strshare_out_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_array_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Array **arr) +{ + if (!arr) return EINA_FALSE; + *arr = eina_array_new(default_step); + eina_array_push(*arr, eina_stringshare_add("0x0")); + eina_array_push(*arr, eina_stringshare_add("0x2A")); + eina_array_push(*arr, eina_stringshare_add("0x42")); + _array_strshare_out_to_check = *arr; + return EINA_TRUE; +} +Eina_Bool _dummy_test_object_check_eina_array_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_array_strshare_out_to_check) return EINA_FALSE; + + Eina_Bool r = _array_strshare_equal(_array_strshare_out_to_check, modified_seq_str, modified_seq_str_size); + + unsigned int i; + Eina_Stringshare *ele; + Eina_Array_Iterator it; + EINA_ARRAY_ITER_NEXT(_array_strshare_out_to_check, i, ele, it) + eina_stringshare_del(ele); + + eina_array_free(_array_strshare_out_to_check); + _array_strshare_out_to_check = NULL; + return r; +} + +Eina_Bool _dummy_test_object_eina_array_strshare_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Array **arr) +{ + if (!arr) return EINA_FALSE; + *arr = eina_array_new(default_step); + eina_array_push(*arr, eina_stringshare_add("0x0")); + eina_array_push(*arr, eina_stringshare_add("0x2A")); + eina_array_push(*arr, eina_stringshare_add("0x42")); + return EINA_TRUE; +} + +Eina_Array *_array_strshare_return_to_check = NULL; + +Eina_Array *_dummy_test_object_eina_array_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Array *arr = eina_array_new(default_step); + eina_array_push(arr, eina_stringshare_add("0x0")); + eina_array_push(arr, eina_stringshare_add("0x2A")); + eina_array_push(arr, eina_stringshare_add("0x42")); + _array_strshare_return_to_check = arr; + return arr; +} +Eina_Bool _dummy_test_object_check_eina_array_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_array_strshare_return_to_check) return EINA_FALSE; + + Eina_Bool r = _array_strshare_equal(_array_strshare_return_to_check, modified_seq_str, modified_seq_str_size); + + unsigned int i; + Eina_Stringshare *ele; + Eina_Array_Iterator it; + EINA_ARRAY_ITER_NEXT(_array_strshare_return_to_check, i, ele, it) + eina_stringshare_del(ele); + + eina_array_free(_array_strshare_return_to_check); + _array_strshare_return_to_check = NULL; + return r; +} + +Eina_Array *_dummy_test_object_eina_array_strshare_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Array *arr = eina_array_new(default_step); + eina_array_push(arr, eina_stringshare_add("0x0")); + eina_array_push(arr, eina_stringshare_add("0x2A")); + eina_array_push(arr, eina_stringshare_add("0x42")); + return arr; +} + // Object Eina_Bool _array_obj_equal(const Eina_Array *arr, const Dummy_Numberwrapper * const base[], unsigned int len) @@ -1488,6 +1630,136 @@ Eina_List *_dummy_test_object_eina_list_str_return_own(EINA_UNUSED Eo *obj, EINA return lst; } +// Eina_Stringshare + +Eina_Bool _list_strshare_equal(const Eina_List *lst, const char * const base[], unsigned int len) +{ + if (eina_list_count(lst) != len) + return EINA_FALSE; + + const Eina_List *l; + Eina_Stringshare *data; + int i = 0; + EINA_LIST_FOREACH(lst, l, data) + { + Eina_Stringshare *ssa = data; + Eina_Stringshare *sse = eina_stringshare_add(base[i]); + if (ssa != sse) + { + fprintf(stderr, "Unexpected stringshare value. Expected: \"%s\" [%p]; Actual: \"%s\" [%p].\n", sse, sse, ssa, ssa); + eina_stringshare_del(sse); + return EINA_FALSE; + } + eina_stringshare_del(sse); + ++i; + } + return EINA_TRUE; +} + +Eina_Bool _dummy_test_object_eina_list_strshare_in(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_List *lst) +{ + Eina_Bool r = _list_strshare_equal(lst, base_seq_str, base_seq_str_size); + return r; +} + +static Eina_List *_list_strshare_in_own_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_list_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_List *lst) +{ + Eina_Bool r = _list_strshare_equal(lst, base_seq_str, base_seq_str_size); + if (!r) return r; + lst = eina_list_append(lst, eina_stringshare_add("42")); + lst = eina_list_append(lst, eina_stringshare_add("43")); + lst = eina_list_append(lst, eina_stringshare_add("33")); + _list_strshare_in_own_to_check = lst; + return r; +} + +Eina_Bool _dummy_test_object_check_eina_list_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_list_strshare_in_own_to_check) return EINA_FALSE; + + Eina_Bool r = _list_strshare_equal(_list_strshare_in_own_to_check, modified_seq_str, modified_seq_str_size); + if (!r) return r; + + Eina_Stringshare *ele; + EINA_LIST_FREE(_list_strshare_in_own_to_check, ele) + eina_stringshare_del(ele); + + _list_strshare_in_own_to_check = NULL; + return r; +} + +Eina_List *_list_strshare_out_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_list_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_List **lst) +{ + if (!lst) return EINA_FALSE; + *lst = eina_list_append(*lst, eina_stringshare_add("0x0")); + *lst = eina_list_append(*lst, eina_stringshare_add("0x2A")); + *lst = eina_list_append(*lst, eina_stringshare_add("0x42")); + _list_strshare_out_to_check = *lst; + return EINA_TRUE; +} +Eina_Bool _dummy_test_object_check_eina_list_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_list_strshare_out_to_check) return EINA_FALSE; + + Eina_Bool r = _list_strshare_equal(_list_strshare_out_to_check, base_seq_str, base_seq_str_size); + if (!r) return r; + + Eina_Stringshare *ele; + EINA_LIST_FREE(_list_strshare_out_to_check, ele) + eina_stringshare_del(ele); + + _list_strshare_out_to_check = NULL; + return r; +} + +Eina_Bool _dummy_test_object_eina_list_strshare_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_List **lst) +{ + if (!lst) return EINA_FALSE; + *lst = eina_list_append(*lst, eina_stringshare_add("0x0")); + *lst = eina_list_append(*lst, eina_stringshare_add("0x2A")); + *lst = eina_list_append(*lst, eina_stringshare_add("0x42")); + return EINA_TRUE; +} + +Eina_List *_list_strshare_return_to_check = NULL; + +Eina_List *_dummy_test_object_eina_list_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_List *lst = NULL; + lst = eina_list_append(lst, eina_stringshare_add("0x0")); + lst = eina_list_append(lst, eina_stringshare_add("0x2A")); + lst = eina_list_append(lst, eina_stringshare_add("0x42")); + _list_strshare_return_to_check = lst; + return lst; +} +Eina_Bool _dummy_test_object_check_eina_list_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_list_strshare_return_to_check) return EINA_FALSE; + + Eina_Bool r = _list_strshare_equal(_list_strshare_return_to_check, base_seq_str, base_seq_str_size); + if (!r) return r; + + Eina_Stringshare *ele; + EINA_LIST_FREE(_list_strshare_return_to_check, ele) + eina_stringshare_del(ele); + + _list_strshare_return_to_check = NULL; + return r; +} + +Eina_List *_dummy_test_object_eina_list_strshare_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_List *lst = NULL; + lst = eina_list_append(lst, eina_stringshare_add("0x0")); + lst = eina_list_append(lst, eina_stringshare_add("0x2A")); + lst = eina_list_append(lst, eina_stringshare_add("0x42")); + return lst; +} + // Object Eina_Bool _list_obj_equal(const Eina_List *lst, const Dummy_Numberwrapper * const base[], unsigned int len) @@ -1923,6 +2195,164 @@ Eina_Inlist *_dummy_test_object_eina_inlist_str_return_own(EINA_UNUSED Eo *obj, return lst; } +// Eina_Stringshare + +typedef struct _Dummy_Inlist_Node_Strshare +{ + EINA_INLIST; + Eina_Stringshare *val; +} Dummy_Inlist_Node_Strshare; + + +Eina_Inlist *_new_inlist_strshare(const char *v) +{ + Dummy_Inlist_Node_Strshare *node = malloc(sizeof(Dummy_Inlist_Node_Strshare)); + node->val = eina_stringshare_add(v); + return EINA_INLIST_GET(node); +} + +Eina_Bool _inlist_strshare_equal(const Eina_Inlist *lst, const char * const base[], unsigned int len) +{ + if (eina_inlist_count(lst) != len) + return EINA_FALSE; + + const Dummy_Inlist_Node_Strshare *node; + int i = 0; + EINA_INLIST_FOREACH(lst, node) + { + Eina_Stringshare *ssa = node->val; + Eina_Stringshare *sse = eina_stringshare_add(base[i]); + if (ssa != sse) + { + fprintf(stderr, "Unexpected stringshare value. Expected: \"%s\" [%p]; Actual: \"%s\" [%p].\n", sse, sse, ssa, ssa); + eina_stringshare_del(sse); + return EINA_FALSE; + } + eina_stringshare_del(sse); + ++i; + } + return EINA_TRUE; +} + +Eina_Bool _dummy_test_object_eina_inlist_strshare_in(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Inlist *lst) +{ + Eina_Bool r = _inlist_strshare_equal(lst, base_seq_str, base_seq_str_size); + return r; +} + +static Eina_Inlist *_inlist_strshare_in_own_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_inlist_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Inlist *lst) +{ + Eina_Bool r = _inlist_strshare_equal(lst, base_seq_str, base_seq_str_size); + if (!r) return r; + lst = eina_inlist_append(lst, _new_inlist_strshare("42")); + lst = eina_inlist_append(lst, _new_inlist_strshare("43")); + lst = eina_inlist_append(lst, _new_inlist_strshare("33")); + _inlist_strshare_in_own_to_check = lst; + return r; +} + +Eina_Bool _dummy_test_object_check_eina_inlist_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Inlist *lst = _inlist_strshare_in_own_to_check; + if (!lst) return EINA_FALSE; + _inlist_strshare_in_own_to_check = NULL; + + Eina_Bool r = _inlist_strshare_equal(lst, modified_seq_str, modified_seq_str_size); + if (!r) return r; + + Dummy_Inlist_Node_Strshare *node; + EINA_INLIST_FREE(lst, node) + { + lst = eina_inlist_remove(lst, EINA_INLIST_GET(node)); + eina_stringshare_del(node->val); + free(node); + } + + return r; +} + +Eina_Inlist *_inlist_strshare_out_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_inlist_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Inlist **lst) +{ + if (!lst) return EINA_FALSE; + *lst = eina_inlist_append(*lst, _new_inlist_strshare("0x0")); + *lst = eina_inlist_append(*lst, _new_inlist_strshare("0x2A")); + *lst = eina_inlist_append(*lst, _new_inlist_strshare("0x42")); + _inlist_strshare_out_to_check = *lst; + return EINA_TRUE; +} +Eina_Bool _dummy_test_object_check_eina_inlist_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Inlist *lst = _inlist_strshare_out_to_check; + if (!lst) return EINA_FALSE; + _inlist_strshare_out_to_check = NULL; + + Eina_Bool r = _inlist_strshare_equal(lst, base_seq_str, base_seq_str_size); + if (!r) return r; + + Dummy_Inlist_Node_Strshare *node; + EINA_INLIST_FREE(lst, node) + { + lst = eina_inlist_remove(lst, EINA_INLIST_GET(node)); + eina_stringshare_del(node->val); + free(node); + } + + return r; +} + +Eina_Bool _dummy_test_object_eina_inlist_strshare_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Inlist **lst) +{ + if (!lst) return EINA_FALSE; + *lst = eina_inlist_append(*lst, _new_inlist_strshare("0x0")); + *lst = eina_inlist_append(*lst, _new_inlist_strshare("0x2A")); + *lst = eina_inlist_append(*lst, _new_inlist_strshare("0x42")); + return EINA_TRUE; +} + +Eina_Inlist *_inlist_strshare_return_to_check = NULL; + +Eina_Inlist *_dummy_test_object_eina_inlist_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Inlist *lst = NULL; + lst = eina_inlist_append(lst, _new_inlist_strshare("0x0")); + lst = eina_inlist_append(lst, _new_inlist_strshare("0x2A")); + lst = eina_inlist_append(lst, _new_inlist_strshare("0x42")); + _inlist_strshare_return_to_check = lst; + return lst; +} +Eina_Bool _dummy_test_object_check_eina_inlist_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Inlist *lst = _inlist_strshare_return_to_check; + if (!lst) return EINA_FALSE; + _inlist_strshare_return_to_check = NULL; + + Eina_Bool r = _inlist_strshare_equal(lst, base_seq_str, base_seq_str_size); + if (!r) return r; + + Dummy_Inlist_Node_Strshare *node; + EINA_INLIST_FREE(lst, node) + { + lst = eina_inlist_remove(lst, EINA_INLIST_GET(node)); + eina_stringshare_del(node->val); + free(node); + } + + return r; +} + +Eina_Inlist *_dummy_test_object_eina_inlist_strshare_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Inlist *lst = NULL; + lst = eina_inlist_append(lst, _new_inlist_strshare("0x0")); + lst = eina_inlist_append(lst, _new_inlist_strshare("0x2A")); + lst = eina_inlist_append(lst, _new_inlist_strshare("0x42")); + return lst; +} + // Object typedef struct _Dummy_Inlist_Node_Obj @@ -2444,6 +2874,194 @@ Eina_Bool _dummy_test_object_check_eina_hash_str_return_own(EINA_UNUSED Eo *obj, } +// Eina_Stringshare // + +Eina_Bool _hash_strshare_check(const Eina_Hash *hsh, const char *key, const char *expected_val) +{ + Eina_Stringshare *ssk = eina_stringshare_add(key); + Eina_Stringshare *sse = eina_stringshare_add(expected_val); + Eina_Stringshare *ssa = eina_hash_find(hsh, ssk); + Eina_Bool result = (ssa == sse); + if (!result) + fprintf(stderr, "Unexpected stringshare value. Expected: \"%s\" [%p]; Actual: \"%s\" [%p].\n", sse, sse, ssa, ssa); + eina_stringshare_del(ssk); + eina_stringshare_del(sse); + return result; +} + +static inline Eina_Bool _hash_strshare_add(Eina_Hash *hsh, const char *key, const char *val) +{ + return eina_hash_add(hsh, eina_stringshare_add(key), eina_stringshare_add(val)); +} + + +// strshare in + +Eina_Bool _dummy_test_object_eina_hash_strshare_in(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Hash *hsh) +{ + if (!_hash_strshare_check(hsh, "aa", "aaa")) + return EINA_FALSE; + + return _hash_strshare_add(hsh, "bb", "bbb"); +} + + +// strshare in own + +static Eina_Bool _hash_strshare_in_own_free_flag = EINA_FALSE; +static void _hash_strshare_in_own_free_cb(void *data) +{ + _hash_strshare_in_own_free_flag = EINA_TRUE; + eina_stringshare_del(data); +} +static Eina_Hash *_hash_strshare_in_own_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_hash_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Hash *hsh) +{ + eina_hash_free_cb_set(hsh, _hash_strshare_in_own_free_cb); + + if (!_hash_strshare_check(hsh, "aa", "aaa")) + return EINA_FALSE; + + _hash_strshare_in_own_to_check = hsh; + + return _hash_strshare_add(hsh, "bb", "bbb"); +} +Eina_Bool _dummy_test_object_check_eina_hash_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_hash_strshare_in_own_to_check) return EINA_FALSE; + + Eina_Hash *hsh = _hash_strshare_in_own_to_check; + + if (!_hash_strshare_check(hsh, "aa", "aaa") + || !_hash_strshare_check(hsh, "bb", "bbb") + || !_hash_strshare_check(hsh, "cc", "ccc")) + return EINA_FALSE; + + eina_hash_free(hsh); + + return _hash_strshare_in_own_free_flag; +} + + +// strshare out + +static Eina_Bool _hash_strshare_out_free_flag = EINA_FALSE; +static void _hash_strshare_out_free_cb(void *data) +{ + _hash_strshare_out_free_flag = EINA_TRUE; + eina_stringshare_del(data); +} +Eina_Hash *_hash_strshare_out_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_hash_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Hash **hsh) +{ + if (!hsh) return EINA_FALSE; + + *hsh = eina_hash_string_superfast_new(_hash_strshare_out_free_cb); + + _hash_strshare_out_to_check = *hsh; + + return _hash_strshare_add(*hsh, "aa", "aaa"); +} +Eina_Bool _dummy_test_object_check_eina_hash_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_hash_strshare_out_to_check) return EINA_FALSE; + + Eina_Hash *hsh = _hash_strshare_out_to_check; + + if (!_hash_strshare_check(hsh, "aa", "aaa") + || !_hash_strshare_check(hsh, "bb", "bbb")) + return EINA_FALSE; + + eina_hash_free(hsh); + + _hash_strshare_out_to_check = NULL; + return _hash_strshare_out_free_flag; +} + + +// strshare out own + +static Eina_Bool _hash_strshare_out_own_free_flag = EINA_FALSE; +static void _hash_strshare_out_own_free_cb(void *data) +{ + _hash_strshare_out_own_free_flag = EINA_TRUE; + eina_stringshare_del(data); +} +Eina_Bool _dummy_test_object_eina_hash_strshare_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Hash **hsh) +{ + if (!hsh) return EINA_FALSE; + + *hsh = eina_hash_string_superfast_new(_hash_strshare_out_own_free_cb); + + return _hash_strshare_add(*hsh, "aa", "aaa"); +} +Eina_Bool _dummy_test_object_check_eina_hash_strshare_out_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + return !_hash_strshare_out_own_free_flag; +} + + +// strshare return + +static Eina_Bool _hash_strshare_return_free_flag = EINA_FALSE; +static void _hash_strshare_return_free_cb(void *data) +{ + _hash_strshare_return_free_flag = EINA_TRUE; + eina_stringshare_del(data); +} +Eina_Hash *_hash_strshare_return_to_check = NULL; + +Eina_Hash *_dummy_test_object_eina_hash_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Hash *hsh = eina_hash_string_superfast_new(_hash_strshare_return_free_cb); + + _hash_strshare_add(hsh, "aa", "aaa"); + + _hash_strshare_return_to_check = hsh; + + return hsh; +} +Eina_Bool _dummy_test_object_check_eina_hash_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + if (!_hash_strshare_return_to_check) return EINA_FALSE; + + Eina_Hash *hsh = _hash_strshare_return_to_check; + + if (!_hash_strshare_check(hsh, "aa", "aaa") + || !_hash_strshare_check(hsh, "bb", "bbb")) + return EINA_FALSE; + + eina_hash_free(hsh); + + _hash_strshare_return_to_check = NULL; + return _hash_strshare_return_free_flag; +} + + +// strshare return own + +static Eina_Bool _hash_strshare_return_own_free_flag = EINA_FALSE; +static void _hash_strshare_return_own_free_cb(void *data) +{ + _hash_strshare_return_own_free_flag = EINA_TRUE; + eina_stringshare_del(data); +} +Eina_Hash *_dummy_test_object_eina_hash_strshare_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Hash *hsh = eina_hash_string_superfast_new(_hash_strshare_return_own_free_cb); + + _hash_strshare_add(hsh, "aa", "aaa"); + + return hsh; +} +Eina_Bool _dummy_test_object_check_eina_hash_strshare_return_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + return !_hash_strshare_return_own_free_flag; +} + + // Object // Eina_Bool _hash_obj_check(const Eina_Hash *hsh, Dummy_Numberwrapper *key, Dummy_Numberwrapper *expected_val, int knum, int vnum) @@ -2966,6 +3584,174 @@ Eina_Iterator *_dummy_test_object_eina_iterator_str_return_own(EINA_UNUSED Eo *o return eina_array_iterator_new(pd->out_array); } +// Eina_Stringshare // + +Eina_Bool _iterator_strshare_equal(Eina_Iterator *itr, const char * const base[], unsigned int len, Eina_Bool release) +{ + Eina_Stringshare *ssa; + unsigned i = 0; + EINA_ITERATOR_FOREACH(itr, ssa) + { + Eina_Stringshare *sse = eina_stringshare_add(base[i]); + if (ssa != sse) + { + fprintf(stderr, "Unexpected stringshare value. Expected: \"%s\" [%p]; Actual: \"%s\" [%p].\n", sse, sse, ssa, ssa); + eina_stringshare_del(sse); + return EINA_FALSE; + } + eina_stringshare_del(sse); + if (release) + eina_stringshare_del(ssa); + ++i; + } + + if (i != len) + return EINA_FALSE; + + return EINA_TRUE; +} + +Eina_Array *_iterator_strshare_eina_array_new() +{ + Eina_Array *arr = eina_array_new(32); + for (unsigned i = 0; i < base_seq_str_size; ++i) + { + eina_array_push(arr, eina_stringshare_add(base_seq_str[i])); + } + return arr; +} + +Eina_Bool _iterator_strshare_test_array(Eina_Array *arr) +{ + if (eina_array_count(arr) != base_seq_str_size) + return EINA_FALSE; + + for (unsigned i = 0; i < base_seq_str_size; ++i) + { + Eina_Stringshare *ssa = eina_array_data_get(arr, i); + Eina_Stringshare *sse = eina_stringshare_add(base_seq_str[i]); + if (ssa != sse) + return EINA_FALSE; + eina_stringshare_del(ssa); + eina_stringshare_del(sse); + } + + eina_array_free(arr); + + return EINA_TRUE; +} + +// in + +Eina_Bool _dummy_test_object_eina_iterator_strshare_in(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Iterator *itr) +{ + Eina_Bool r = _iterator_strshare_equal(itr, base_seq_str, base_seq_str_size, EINA_FALSE); + return r; +} + +// in own + +static Eina_Iterator *_iterator_strshare_in_own_to_check = NULL; + +Eina_Bool _dummy_test_object_eina_iterator_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Iterator *itr) +{ + Eina_Bool r = _iterator_strshare_equal(itr, base_seq_str, base_seq_str_size, EINA_FALSE); + _iterator_strshare_in_own_to_check = itr; + return r; +} +Eina_Bool _dummy_test_object_check_eina_iterator_strshare_in_own(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + eina_iterator_free(_iterator_strshare_in_own_to_check); + _iterator_strshare_in_own_to_check = NULL; + return EINA_TRUE; +} + +// out + +Eina_Iterator *_iterator_strshare_out_to_check = NULL; +Eina_Array *_iterator_strshare_out_array = NULL; + +Eina_Bool _dummy_test_object_eina_iterator_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Iterator **itr) +{ + if (!itr) return EINA_FALSE; + + _iterator_strshare_out_array = _iterator_strshare_eina_array_new(); + + *itr = eina_array_iterator_new(_iterator_strshare_out_array); + _iterator_strshare_out_to_check = *itr; + + return EINA_TRUE; +} +Eina_Bool _dummy_test_object_check_eina_iterator_strshare_out(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Iterator *itr = _iterator_strshare_out_to_check; + if (!itr) return EINA_FALSE; + _iterator_strshare_out_to_check = NULL; + + Eina_Array *arr = _iterator_strshare_out_array; + if (!arr) return EINA_FALSE; + _iterator_strshare_out_array = NULL; + + Eina_Bool r = _iterator_strshare_test_array(arr); + if (!r) return r; + + eina_iterator_free(itr); + + return r; +} + +// out own + +Eina_Bool _dummy_test_object_eina_iterator_strshare_out_own(EINA_UNUSED Eo *obj, Dummy_Test_Object_Data *pd, Eina_Iterator **itr) +{ + if (!itr) return EINA_FALSE; + + pd->out_array = _iterator_strshare_eina_array_new(); + pd->out_array_free_element_cb = (Eina_Free_Cb) eina_stringshare_del; + + *itr = eina_array_iterator_new(pd->out_array); + + return EINA_TRUE; +} + +// return + +Eina_Iterator *_iterator_strshare_return_to_check = NULL; +Eina_Array *_iterator_strshare_return_array = NULL; + +Eina_Iterator *_dummy_test_object_eina_iterator_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + _iterator_strshare_return_array = _iterator_strshare_eina_array_new(); + _iterator_strshare_return_to_check = eina_array_iterator_new(_iterator_strshare_return_array); + return _iterator_strshare_return_to_check; +} +Eina_Bool _dummy_test_object_check_eina_iterator_strshare_return(EINA_UNUSED Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd) +{ + Eina_Iterator *itr = _iterator_strshare_return_to_check; + if (!itr) return EINA_FALSE; + _iterator_strshare_return_to_check = NULL; + + Eina_Array *arr = _iterator_strshare_return_array; + if (!arr) return EINA_FALSE; + _iterator_strshare_return_array = NULL; + + Eina_Bool r = _iterator_strshare_test_array(arr); + if (!r) return r; + + eina_iterator_free(itr); + + return r; +} + +// return own + +Eina_Iterator *_dummy_test_object_eina_iterator_strshare_return_own(EINA_UNUSED Eo *obj, Dummy_Test_Object_Data *pd) +{ + pd->out_array = _iterator_strshare_eina_array_new(); + pd->out_array_free_element_cb = (Eina_Free_Cb) eina_stringshare_del; + return eina_array_iterator_new(pd->out_array); +} + // Object // Eina_Bool _iterator_obj_equal(Eina_Iterator *itr, const Dummy_Numberwrapper * const base[], unsigned int len, Eina_Bool release) diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo index 529b246418..22c9d69eb8 100644 --- a/src/tests/efl_mono/dummy_test_object.eo +++ b/src/tests/efl_mono/dummy_test_object.eo @@ -468,6 +468,52 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { return: array @owned; } + /* Eina_Stringshare */ + eina_array_strshare_in { + params { + @in arr: array; + } + return: bool; + } + + eina_array_strshare_in_own { + params { + @in arr: array @owned; + } + return: bool; + } + check_eina_array_strshare_in_own { + return: bool; + } + + eina_array_strshare_out { + params { + @out arr: array; + } + return: bool; + } + check_eina_array_strshare_out { + return: bool; + } + + eina_array_strshare_out_own { + params { + @out arr: array @owned; + } + return: bool; + } + + eina_array_strshare_return { + return: array; + } + check_eina_array_strshare_return { + return: bool; + } + + eina_array_strshare_return_own { + return: array @owned; + } + /* Object */ eina_array_obj_in { params { @@ -615,6 +661,52 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { return: list @owned; } + /* Eina_Stringshare */ + eina_list_strshare_in { + params { + @in lst: list; + } + return: bool; + } + + eina_list_strshare_in_own { + params { + @in lst: list @owned; + } + return: bool; + } + check_eina_list_strshare_in_own { + return: bool; + } + + eina_list_strshare_out { + params { + @out lst: list; + } + return: bool; + } + check_eina_list_strshare_out { + return: bool; + } + + eina_list_strshare_out_own { + params { + @out lst: list @owned; + } + return: bool; + } + + eina_list_strshare_return { + return: list; + } + check_eina_list_strshare_return { + return: bool; + } + + eina_list_strshare_return_own { + return: list @owned; + } + /* Object */ eina_list_obj_in { params { @@ -774,6 +866,58 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { return: bool; } + // Eina_Stringshare // + eina_hash_strshare_in { + params { + @in hsh: hash; + } + return: bool; + } + + eina_hash_strshare_in_own { + params { + @in hsh: hash @owned; + } + return: bool; + } + check_eina_hash_strshare_in_own { + return: bool; + } + + eina_hash_strshare_out { + params { + @out hsh: hash; + } + return: bool; + } + check_eina_hash_strshare_out { + return: bool; + } + + eina_hash_strshare_out_own { + params { + @out hsh: hash @owned; + } + return: bool; + } + check_eina_hash_strshare_out_own { + return: bool; + } + + eina_hash_strshare_return { + return: hash; + } + check_eina_hash_strshare_return { + return: bool; + } + + eina_hash_strshare_return_own { + return: hash @owned; + } + check_eina_hash_strshare_return_own { + return: bool; + } + // Object // eina_hash_obj_in { params { @@ -958,6 +1102,52 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface { return: iterator @owned; } + /* Eina_Stringshare */ + eina_iterator_strshare_in { + params { + @in itr: iterator; + } + return: bool; + } + + eina_iterator_strshare_in_own { + params { + @in itr: iterator @owned; + } + return: bool; + } + check_eina_iterator_strshare_in_own { + return: bool; + } + + eina_iterator_strshare_out { + params { + @out itr: iterator; + } + return: bool; + } + check_eina_iterator_strshare_out { + return: bool; + } + + eina_iterator_strshare_out_own { + params { + @out itr: iterator @owned; + } + return: bool; + } + + eina_iterator_strshare_return { + return: iterator; + } + check_eina_iterator_strshare_return { + return: bool; + } + + eina_iterator_strshare_return_own { + return: iterator @owned; + } + /* Object */ eina_iterator_obj_in { params { From 229b363f0103e15e5b8f3958b501a993c7fe254c Mon Sep 17 00:00:00 2001 From: Vitor Sousa Date: Fri, 28 Jun 2019 10:58:24 -0300 Subject: [PATCH 36/36] csharp: fix some compilation warnings Fix unused variable warnings in eina_mono and unit test files. --- src/bindings/mono/eina_mono/eina_value.cs | 2 +- src/tests/efl_mono/dummy_constructible_object.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs index a19d3d449b..898a4966bb 100644 --- a/src/bindings/mono/eina_mono/eina_value.cs +++ b/src/bindings/mono/eina_mono/eina_value.cs @@ -732,7 +732,7 @@ static class ValueTypeBridge { return NativeToManaged[native]; } - catch (KeyNotFoundException ex) + catch (KeyNotFoundException) { var name_ptr = eina_value_type_name_get(native); var name = Marshal.PtrToStringAnsi(name_ptr); diff --git a/src/tests/efl_mono/dummy_constructible_object.c b/src/tests/efl_mono/dummy_constructible_object.c index 870895066c..ec4d22de60 100644 --- a/src/tests/efl_mono/dummy_constructible_object.c +++ b/src/tests/efl_mono/dummy_constructible_object.c @@ -69,7 +69,7 @@ _dummy_constructible_object_internal_object_get(const Eo *obj EINA_UNUSED, Dummy EOLIAN static int -_dummy_constructible_object_multiply_integer_value(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd, int v) +_dummy_constructible_object_multiply_integer_value(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd EINA_UNUSED, int v) { return 2 * v; }