forked from enlightenment/efl
256 lines
7.1 KiB
C
256 lines
7.1 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <Eo.h>
|
|
|
|
#include "eo_suite.h"
|
|
#include "eo_test_class_simple.h"
|
|
|
|
//Class definition with one event
|
|
|
|
EO_API_WEAK const Efl_Class *efl_test_event_class_get(void) EINA_CONST;
|
|
|
|
EO_API_WEAK extern const Efl_Event_Description _EFL_TEST_EVENT_EVENT_TESTER;
|
|
EO_API_WEAK extern const Efl_Event_Description _EFL_TEST_EVENT_EVENT_TESTER_SUBSCRIBE;
|
|
EO_API_WEAK extern const Efl_Event_Description _EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST;
|
|
|
|
#define EFL_TEST_EVENT_EVENT_TESTER (&(_EFL_TEST_EVENT_EVENT_TESTER))
|
|
#define EFL_TEST_EVENT_EVENT_TESTER_SUBSCRIBE (&(_EFL_TEST_EVENT_EVENT_TESTER_SUBSCRIBE))
|
|
#define EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST (&(_EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST))
|
|
|
|
typedef struct {
|
|
Eina_Bool event1;
|
|
Eina_Bool event2;
|
|
Eina_Bool event3;
|
|
} Test_Data;
|
|
|
|
typedef struct {
|
|
int not_empty;
|
|
} Efl_Test_Event_Data;
|
|
|
|
static void
|
|
_cb3(void *data, const Efl_Event *event EINA_UNUSED)
|
|
{
|
|
Test_Data *d = data;
|
|
|
|
d->event3 = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_cb2(void *data, const Efl_Event *event EINA_UNUSED)
|
|
{
|
|
Test_Data *d = data;
|
|
|
|
d->event2 = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_cb1(void *data, const Efl_Event *event)
|
|
{
|
|
Test_Data *d = data;
|
|
|
|
d->event1 = EINA_TRUE;
|
|
|
|
efl_event_callback_add(event->object, EFL_TEST_EVENT_EVENT_TESTER, _cb3, data);
|
|
}
|
|
|
|
EFL_START_TEST(eo_event)
|
|
{
|
|
Test_Data data;
|
|
Eo *obj;
|
|
|
|
obj = efl_add_ref(efl_test_event_class_get(), NULL);
|
|
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, _cb2, &data);
|
|
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, _cb1, &data);
|
|
|
|
memset(&data, 0, sizeof(Test_Data));
|
|
efl_event_callback_call(obj, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
ck_assert_int_ne(data.event1, 0);
|
|
ck_assert_int_ne(data.event2, 0);
|
|
ck_assert_int_eq(data.event3, 0);
|
|
|
|
memset(&data, 0, sizeof(Test_Data));
|
|
efl_event_callback_call(obj, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
ck_assert_int_ne(data.event1, 0);
|
|
ck_assert_int_ne(data.event2, 0);
|
|
ck_assert_int_ne(data.event3, 0);
|
|
|
|
}
|
|
EFL_END_TEST
|
|
|
|
static void
|
|
_cb_rec_3(void *data EINA_UNUSED, const Efl_Event *event)
|
|
{
|
|
Test_Data *d = event->info;
|
|
ck_assert_int_eq(d->event3, 0);
|
|
d->event3 = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_cb_rec_2(void *data EINA_UNUSED, const Efl_Event *event)
|
|
{
|
|
Test_Data *d = event->info;
|
|
ck_assert_int_eq(d->event2, 0);
|
|
d->event2 = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_cb_rec_1(void *data, const Efl_Event *event)
|
|
{
|
|
Test_Data *d = event->info;
|
|
|
|
if (event->info)
|
|
{
|
|
ck_assert_int_eq(d->event1, 0);
|
|
d->event1 = EINA_TRUE;
|
|
}
|
|
else
|
|
{
|
|
efl_event_callback_add(event->object , EFL_TEST_EVENT_EVENT_TESTER, _cb_rec_2, NULL);
|
|
efl_event_callback_add(event->object , EFL_TEST_EVENT_EVENT_TESTER, _cb_rec_3, NULL);
|
|
efl_event_callback_call(event->object, EFL_TEST_EVENT_EVENT_TESTER, data);
|
|
}
|
|
}
|
|
|
|
EFL_START_TEST(eo_event_call_in_call)
|
|
{
|
|
Test_Data data;
|
|
Eo *obj;
|
|
|
|
obj = efl_add_ref(efl_test_event_class_get(), NULL);
|
|
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, _cb_rec_1, &data);
|
|
|
|
memset(&data, 0, sizeof(Test_Data));
|
|
efl_event_callback_call(obj, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
ck_assert_int_ne(data.event1, 0);
|
|
ck_assert_int_ne(data.event2, 0);
|
|
ck_assert_int_ne(data.event3, 0);
|
|
|
|
}
|
|
EFL_END_TEST
|
|
|
|
static Eina_Bool emitted = 0;
|
|
|
|
static void
|
|
_generation_clamp_step3(void *data EINA_UNUSED, const Efl_Event *e EINA_UNUSED)
|
|
{
|
|
emitted = 1;
|
|
}
|
|
|
|
static void
|
|
_generation_clamp_subscribe(void *data EINA_UNUSED, const Efl_Event *e)
|
|
{
|
|
//generation is 2
|
|
efl_event_callback_add(e->object, EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST, _generation_clamp_step3, NULL);
|
|
}
|
|
|
|
static void
|
|
_generation_clamp_step1(void *data EINA_UNUSED, const Efl_Event *e)
|
|
{
|
|
//generation is 1
|
|
efl_event_callback_call(e->object, EFL_TEST_EVENT_EVENT_TESTER_SUBSCRIBE, NULL);
|
|
|
|
efl_event_callback_call(e->object, EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST, NULL);
|
|
efl_event_callback_call(e->object, EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST, NULL);
|
|
}
|
|
|
|
|
|
EFL_START_TEST(eo_event_generation_bug)
|
|
{
|
|
|
|
/*
|
|
* The idea is:
|
|
*
|
|
* #1 a event gets emitted (generation is 1)
|
|
* #2 a event gets emitted as a result of #1 (generation is 2)
|
|
* in a callback from #2 a new subscription for E is added (S) (generation of it is 2)
|
|
* in a callback of #1 event E is emitted (generation is 2)
|
|
* S now MUST get executed (Here is the bug generation of S is 2 and of emission is 2, event gets skipped)
|
|
* subscription adds a callback to a event
|
|
*/
|
|
|
|
Eo *obj;
|
|
|
|
obj = efl_add_ref(efl_test_event_class_get(), NULL);
|
|
emitted = 0;
|
|
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, _generation_clamp_step1, NULL);
|
|
efl_event_callback_priority_add(obj, EFL_TEST_EVENT_EVENT_TESTER_SUBSCRIBE, EFL_CALLBACK_PRIORITY_BEFORE, _generation_clamp_subscribe, NULL);
|
|
efl_event_callback_call(obj, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
|
|
ck_assert_int_ne(emitted, 0);
|
|
|
|
}
|
|
EFL_END_TEST
|
|
|
|
static void
|
|
_inc_when_called(void *data, const Efl_Event *ev EINA_UNUSED)
|
|
{
|
|
int *called = (int*)data;
|
|
*called += 1;
|
|
}
|
|
|
|
EFL_START_TEST(eo_event_fowarder_test)
|
|
{
|
|
Eo *obj1, *obj2;
|
|
int called = 0;
|
|
|
|
obj1 = efl_add_ref(efl_test_event_class_get(), NULL);
|
|
obj2 = efl_add_ref(efl_test_event_class_get(), NULL);
|
|
efl_event_callback_add(obj2, EFL_TEST_EVENT_EVENT_TESTER, _inc_when_called, &called);
|
|
|
|
efl_event_callback_forwarder_priority_add(obj1, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, obj2);
|
|
efl_event_callback_call(obj1, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
ck_assert_int_eq(called, 1);
|
|
called = 0;
|
|
|
|
//call it a second time with another forwarder
|
|
efl_event_callback_forwarder_priority_add(obj1, EFL_TEST_EVENT_EVENT_TESTER, EFL_CALLBACK_PRIORITY_BEFORE, obj2);
|
|
efl_event_callback_call(obj1, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
ck_assert_int_eq(called, 1); //we still should only emit it once
|
|
called = 0;
|
|
|
|
//delete it, nothing should happen now
|
|
efl_event_callback_forwarder_del(obj1, EFL_TEST_EVENT_EVENT_TESTER, obj2);
|
|
efl_event_callback_call(obj1, EFL_TEST_EVENT_EVENT_TESTER, NULL);
|
|
ck_assert_int_eq(called, 0);
|
|
|
|
}
|
|
EFL_END_TEST
|
|
|
|
void eo_test_event(TCase *tc)
|
|
{
|
|
tcase_add_test(tc, eo_event);
|
|
tcase_add_test(tc, eo_event_call_in_call);
|
|
tcase_add_test(tc, eo_event_generation_bug);
|
|
tcase_add_test(tc, eo_event_fowarder_test);
|
|
}
|
|
|
|
|
|
|
|
//class implementation
|
|
|
|
EO_API_WEAK const Efl_Event_Description _EFL_TEST_EVENT_EVENT_TESTER =
|
|
EFL_EVENT_DESCRIPTION("tester");
|
|
|
|
EO_API_WEAK const Efl_Event_Description _EFL_TEST_EVENT_EVENT_TESTER_SUBSCRIBE =
|
|
EFL_EVENT_DESCRIPTION("tester");
|
|
|
|
EO_API_WEAK const Efl_Event_Description _EFL_TEST_EVENT_EVENT_TESTER_CLAMP_TEST =
|
|
EFL_EVENT_DESCRIPTION("tester");
|
|
|
|
|
|
static const Efl_Class_Description _efl_test_event_class_desc = {
|
|
EO_VERSION,
|
|
"Efl_Test_Event",
|
|
EFL_CLASS_TYPE_REGULAR,
|
|
sizeof(Efl_Test_Event_Data),
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
};
|
|
|
|
EFL_DEFINE_CLASS(efl_test_event_class_get, &_efl_test_event_class_desc, EFL_OBJECT_CLASS, NULL);
|