1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <unistd.h>
9 #include <math.h>
10
11 #include "Ecore.h"
12 #include "ecore_private.h"
13
14 #define MY_CLASS EFL_LOOP_MESSAGE_HANDLER_CLASS
15
16 #include "ecore_main_common.h"
17
18 typedef struct _Efl_Loop_Message_Handler_Data Efl_Loop_Message_Handler_Data;
19
20 struct _Efl_Loop_Message_Handler_Data
21 {
22 Eo *loop;
23 Efl_Loop_Data *loop_data;
24 };
25
26 EOLIAN static Efl_Loop_Message *
_efl_loop_message_handler_message_add(Eo * obj,Efl_Loop_Message_Handler_Data * pd EINA_UNUSED)27 _efl_loop_message_handler_message_add(Eo *obj, Efl_Loop_Message_Handler_Data *pd EINA_UNUSED)
28 {
29 // XXX: implement message object cache
30 Efl_Loop_Message *message = efl_add(EFL_LOOP_MESSAGE_CLASS, obj);
31 if (!message) return NULL;
32 // XXX: track added messages not sent yet ...
33 return message;
34 }
35
36 EOLIAN static void
_efl_loop_message_handler_message_send(Eo * obj,Efl_Loop_Message_Handler_Data * pd,Efl_Loop_Message * message)37 _efl_loop_message_handler_message_send(Eo *obj, Efl_Loop_Message_Handler_Data *pd, Efl_Loop_Message *message)
38 {
39 Message *msg;
40
41 if (EINA_UNLIKELY(!pd->loop))
42 {
43 pd->loop = efl_provider_find(obj, EFL_LOOP_CLASS);
44 if (!pd->loop) return;
45 pd->loop_data = efl_data_scope_get(pd->loop, EFL_LOOP_CLASS);
46 if (!pd->loop_data)
47 {
48 pd->loop = NULL;
49 return;
50 }
51 }
52 msg = calloc(1, sizeof(Message));
53 if (msg)
54 {
55 msg->handler = obj;
56 msg->message = message;
57 if (pd->loop_data->message_walking > 0)
58 {
59 pd->loop_data->message_pending_queue = eina_inlist_append
60 (pd->loop_data->message_pending_queue, EINA_INLIST_GET(msg));
61 }
62 else
63 {
64 pd->loop_data->message_queue = eina_inlist_append
65 (pd->loop_data->message_queue, EINA_INLIST_GET(msg));
66 }
67 _efl_loop_message_send_info_set(message, EINA_INLIST_GET(msg),
68 pd->loop, pd->loop_data);
69 return;
70 }
71 efl_del(message);
72 }
73
74 EOLIAN static void
_efl_loop_message_handler_message_call(Eo * obj,Efl_Loop_Message_Handler_Data * pd,Efl_Loop_Message * message)75 _efl_loop_message_handler_message_call(Eo *obj, Efl_Loop_Message_Handler_Data *pd, Efl_Loop_Message *message)
76 {
77 Message *msg;
78 unsigned int n = 0;
79 Eina_Bool found = EINA_FALSE;
80
81 if (!pd->loop) return;
82 EINA_INLIST_FOREACH(pd->loop_data->message_queue, msg)
83 {
84 n++;
85 if (msg->message != message) continue;
86 found = EINA_TRUE;
87 msg->message = NULL;
88 msg->handler = NULL;
89 _efl_loop_message_send_info_set(message, NULL, NULL, NULL);
90 if ((pd->loop_data->message_walking == 0) || (n == 1))
91 {
92 pd->loop_data->message_queue =
93 eina_inlist_remove(pd->loop_data->message_queue,
94 EINA_INLIST_GET(msg));
95 free(msg);
96 }
97 else
98 msg->delete_me = EINA_TRUE;
99 break;
100 }
101 efl_event_callback_call(message, EFL_LOOP_MESSAGE_EVENT_MESSAGE,
102 message);
103 efl_event_callback_call(obj, EFL_LOOP_MESSAGE_HANDLER_EVENT_MESSAGE,
104 message);
105 // XXX: implement message object cache...
106 if (message) efl_del(message);
107 if (found) return;
108 ERR("Cannot find message called object %p on message queue", message);
109 }
110
111 EOLIAN static Eina_Bool
_efl_loop_message_handler_message_clear(Eo * obj,Efl_Loop_Message_Handler_Data * pd)112 _efl_loop_message_handler_message_clear(Eo *obj, Efl_Loop_Message_Handler_Data *pd)
113 {
114 Eina_Inlist *tmp;
115 Message *msg;
116
117 if (!pd->loop) return EINA_FALSE;
118 if (!pd->loop_data->message_queue) return EINA_FALSE;
119 EINA_INLIST_FOREACH_SAFE(pd->loop_data->message_queue, tmp, msg)
120 {
121 if (msg->handler == obj)
122 {
123 Eo *message = msg->message;
124
125 msg->delete_me = EINA_TRUE;
126 msg->handler = NULL;
127 msg->message = NULL;
128 _efl_loop_message_send_info_set(message, NULL, NULL, NULL);
129 if (pd->loop_data->message_walking == 0)
130 {
131 pd->loop_data->message_queue =
132 eina_inlist_remove(pd->loop_data->message_queue,
133 EINA_INLIST_GET(msg));
134 free(msg);
135 }
136 if (message) efl_del(message);
137 }
138 }
139 return EINA_FALSE;
140 }
141
142 EOLIAN static Efl_Object *
_efl_loop_message_handler_efl_object_constructor(Eo * obj,Efl_Loop_Message_Handler_Data * pd EINA_UNUSED)143 _efl_loop_message_handler_efl_object_constructor(Eo *obj, Efl_Loop_Message_Handler_Data *pd EINA_UNUSED)
144 {
145 obj = efl_constructor(efl_super(obj, MY_CLASS));
146 return obj;
147 }
148
149 EOLIAN static void
_efl_loop_message_handler_efl_object_destructor(Eo * obj,Efl_Loop_Message_Handler_Data * pd EINA_UNUSED)150 _efl_loop_message_handler_efl_object_destructor(Eo *obj, Efl_Loop_Message_Handler_Data *pd EINA_UNUSED)
151 {
152 efl_destructor(efl_super(obj, MY_CLASS));
153 }
154
155 #include "efl_loop_message_handler.eo.c"
156