aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/edje/src/lib/edje_message_queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/edje/src/lib/edje_message_queue.c')
-rw-r--r--libraries/edje/src/lib/edje_message_queue.c865
1 files changed, 865 insertions, 0 deletions
diff --git a/libraries/edje/src/lib/edje_message_queue.c b/libraries/edje/src/lib/edje_message_queue.c
new file mode 100644
index 0000000..1a313a5
--- /dev/null
+++ b/libraries/edje/src/lib/edje_message_queue.c
@@ -0,0 +1,865 @@
1#include "edje_private.h"
2
3static void _edje_object_message_popornot_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg, Eina_Bool prop);
4
5static int _injob = 0;
6static Ecore_Job *_job = NULL;
7static Ecore_Timer *_job_loss_timer = NULL;
8
9static Eina_List *msgq = NULL;
10static Eina_List *tmp_msgq = NULL;
11static int tmp_msgq_processing = 0;
12static int tmp_msgq_restart = 0;
13
14/*============================================================================*
15 * API *
16 *============================================================================*/
17
18static void
19_edje_object_message_popornot_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg, Eina_Bool prop)
20{
21 Edje *ed;
22 Eina_List *l;
23 Evas_Object *o;
24
25 ed = _edje_fetch(obj);
26 if (!ed) return;
27 _edje_message_propornot_send(ed, EDJE_QUEUE_SCRIPT, type, id, msg, prop);
28 EINA_LIST_FOREACH(ed->subobjs, l, o)
29 {
30 _edje_object_message_popornot_send(o, type, id, msg, EINA_TRUE);
31 }
32}
33
34EAPI void
35edje_object_message_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg)
36{
37 _edje_object_message_popornot_send(obj, type, id, msg, EINA_FALSE);
38}
39
40
41EAPI void
42edje_object_message_handler_set(Evas_Object *obj, Edje_Message_Handler_Cb func, void *data)
43{
44 Edje *ed;
45
46 ed = _edje_fetch(obj);
47 if (!ed) return;
48 _edje_message_cb_set(ed, func, data);
49}
50
51
52EAPI void
53edje_object_message_signal_process(Evas_Object *obj)
54{
55 Eina_List *l, *ln, *tmpq = NULL;
56 Edje *ed;
57 Edje_Message *em;
58 int gotos = 0;
59
60 ed = _edje_fetch(obj);
61 if (!ed) return;
62
63 for (l = msgq; l; )
64 {
65 ln = l->next;
66 em = l->data;
67 if (em->edje == ed)
68 {
69 tmpq = eina_list_append(tmpq, em);
70 msgq = eina_list_remove_list(msgq, l);
71 }
72 l = ln;
73 }
74 /* a temporary message queue */
75 if (tmp_msgq)
76 {
77 while (tmpq)
78 {
79 tmp_msgq = eina_list_append(tmp_msgq, tmpq->data);
80 tmpq = eina_list_remove_list(tmpq, tmpq);
81 }
82 }
83 else
84 {
85 tmp_msgq = tmpq;
86 tmpq = NULL;
87 }
88
89 tmp_msgq_processing++;
90again:
91 EINA_LIST_FOREACH_SAFE(tmp_msgq, l, ln, em)
92 {
93 if (em->edje != ed) continue;
94 tmp_msgq = eina_list_remove_list(tmp_msgq, l);
95 if (!ed->delete_me)
96 {
97 ed->processing_messages++;
98 _edje_message_process(em);
99 _edje_message_free(em);
100 ed->processing_messages--;
101 }
102 else
103 _edje_message_free(em);
104 if (ed->processing_messages == 0)
105 {
106 if (ed->delete_me) _edje_del(ed);
107 }
108 // if some child callback in _edje_message_process called
109 // edje_object_message_signal_process() or
110 // edje_message_signal_process() then those will mark the restart
111 // flag when they finish - it mabsicammyt means tmp_msgq and
112 // any item in it has potentially become invalid - so that means l
113 // and ln could be rogue pointers, so start again from the beginning
114 // and skip anything that is not this object and process only what is.
115 // to avoid self-feeding loops allow a max of 1024 loops.
116 if (tmp_msgq_restart)
117 {
118 tmp_msgq_restart = 0;
119 gotos++;
120 if (gotos < 1024) goto again;
121 else
122 {
123 WRN("Edje is in a self-feeding message loop (> 1024 gotos needed in a row)");
124 goto end;
125 }
126 }
127 }
128end:
129 tmp_msgq_processing--;
130 if (tmp_msgq_processing == 0)
131 tmp_msgq_restart = 0;
132 else
133 tmp_msgq_restart = 1;
134}
135
136
137EAPI void
138edje_message_signal_process(void)
139{
140 _edje_message_queue_process();
141}
142
143
144static Eina_Bool
145_edje_dummy_timer(void *data __UNUSED__)
146{
147 return ECORE_CALLBACK_CANCEL;
148}
149
150static void
151_edje_job(void *data __UNUSED__)
152{
153 if (_job_loss_timer)
154 {
155 ecore_timer_del(_job_loss_timer);
156 _job_loss_timer = NULL;
157 }
158 _job = NULL;
159 _injob++;
160 _edje_message_queue_process();
161 _injob--;
162}
163
164static Eina_Bool
165_edje_job_loss_timer(void *data __UNUSED__)
166{
167 _job_loss_timer = NULL;
168 if (!_job)
169 {
170 _job = ecore_job_add(_edje_job, NULL);
171 }
172 return ECORE_CALLBACK_CANCEL;
173}
174
175void
176_edje_message_init(void)
177{
178}
179
180void
181_edje_message_shutdown(void)
182{
183 _edje_message_queue_clear();
184 if (_job_loss_timer)
185 {
186 ecore_timer_del(_job_loss_timer);
187 _job_loss_timer = NULL;
188 }
189 if (_job)
190 {
191 ecore_job_del(_job);
192 _job = NULL;
193 }
194}
195
196void
197_edje_message_cb_set(Edje *ed, void (*func) (void *data, Evas_Object *obj, Edje_Message_Type type, int id, void *msg), void *data)
198{
199 Eina_List *l;
200 Evas_Object *o;
201
202 ed->message.func = func;
203 ed->message.data = data;
204 EINA_LIST_FOREACH(ed->subobjs, l, o)
205 {
206 Edje *edj2 = _edje_fetch(o);
207 if (!edj2) continue;
208 _edje_message_cb_set(edj2, func, data);
209 }
210}
211
212Edje_Message *
213_edje_message_new(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id)
214{
215 Edje_Message *em;
216
217 em = calloc(1, sizeof(Edje_Message));
218 if (!em) return NULL;
219 em->edje = ed;
220 em->queue = queue;
221 em->type = type;
222 em->id = id;
223 em->edje->message.num++;
224 return em;
225}
226
227void
228_edje_message_free(Edje_Message *em)
229{
230 if (em->msg)
231 {
232 int i;
233
234 switch (em->type)
235 {
236 case EDJE_MESSAGE_STRING:
237 {
238 Edje_Message_String *emsg;
239
240 emsg = (Edje_Message_String *)em->msg;
241 free(emsg->str);
242 free(emsg);
243 }
244 break;
245 case EDJE_MESSAGE_INT:
246 {
247 Edje_Message_Int *emsg;
248
249 emsg = (Edje_Message_Int *)em->msg;
250 free(emsg);
251 }
252 break;
253 case EDJE_MESSAGE_FLOAT:
254 {
255 Edje_Message_Float *emsg;
256
257 emsg = (Edje_Message_Float *)em->msg;
258 free(emsg);
259 }
260 break;
261 case EDJE_MESSAGE_INT_SET:
262 {
263 Edje_Message_Int_Set *emsg;
264
265 emsg = (Edje_Message_Int_Set *)em->msg;
266 free(emsg);
267 }
268 break;
269 case EDJE_MESSAGE_FLOAT_SET:
270 {
271 Edje_Message_Float_Set *emsg;
272
273 emsg = (Edje_Message_Float_Set *)em->msg;
274 free(emsg);
275 }
276 break;
277 case EDJE_MESSAGE_STRING_FLOAT:
278 {
279 Edje_Message_String_Float *emsg;
280
281 emsg = (Edje_Message_String_Float *)em->msg;
282 free(emsg->str);
283 free(emsg);
284 }
285 break;
286 case EDJE_MESSAGE_STRING_INT:
287 {
288 Edje_Message_String_Int *emsg;
289
290 emsg = (Edje_Message_String_Int *)em->msg;
291 free(emsg->str);
292 free(emsg);
293 }
294 break;
295 case EDJE_MESSAGE_STRING_FLOAT_SET:
296 {
297 Edje_Message_String_Float_Set *emsg;
298
299 emsg = (Edje_Message_String_Float_Set *)em->msg;
300 free(emsg->str);
301 free(emsg);
302 }
303 break;
304 case EDJE_MESSAGE_STRING_INT_SET:
305 {
306 Edje_Message_String_Int_Set *emsg;
307
308 emsg = (Edje_Message_String_Int_Set *)em->msg;
309 free(emsg->str);
310 free(emsg);
311 }
312 break;
313 case EDJE_MESSAGE_SIGNAL:
314 {
315 Edje_Message_Signal *emsg;
316
317 emsg = (Edje_Message_Signal *)em->msg;
318 if (emsg->sig) eina_stringshare_del(emsg->sig);
319 if (emsg->src) eina_stringshare_del(emsg->src);
320 if (emsg->data && (--(emsg->data->ref) == 0))
321 {
322 if (emsg->data->free_func)
323 {
324 emsg->data->free_func(emsg->data->data);
325 }
326 free(emsg->data);
327 }
328 free(emsg);
329 }
330 break;
331 case EDJE_MESSAGE_STRING_SET:
332 {
333 Edje_Message_String_Set *emsg;
334
335 emsg = (Edje_Message_String_Set *)em->msg;
336 for (i = 0; i < emsg->count; i++)
337 free(emsg->str[i]);
338 free(emsg);
339 }
340 break;
341 case EDJE_MESSAGE_NONE:
342 default:
343 break;
344 }
345 }
346 free(em);
347}
348
349void
350_edje_message_propornot_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg, Eina_Bool prop)
351{
352 /* FIXME: check all malloc & strdup fails and gracefully unroll and exit */
353 Edje_Message *em;
354 int i;
355 unsigned char *msg = NULL;
356
357 em = _edje_message_new(ed, queue, type, id);
358 if (!em) return;
359 em->propagated = prop;
360 if (_job)
361 {
362 ecore_job_del(_job);
363 _job = NULL;
364 }
365 if (_injob > 0)
366 {
367 if (_job_loss_timer) ecore_timer_del(_job_loss_timer);
368 _job_loss_timer = ecore_timer_add(0.001, _edje_job_loss_timer, NULL);
369 }
370 else
371 {
372 if (!_job)
373 {
374 _job = ecore_job_add(_edje_job, NULL);
375 }
376 if (_job_loss_timer)
377 {
378 ecore_timer_del(_job_loss_timer);
379 _job_loss_timer = NULL;
380 }
381 }
382 switch (em->type)
383 {
384 case EDJE_MESSAGE_NONE:
385 break;
386 case EDJE_MESSAGE_SIGNAL:
387 {
388 Edje_Message_Signal *emsg2, *emsg3;
389
390 emsg2 = (Edje_Message_Signal *)emsg;
391 emsg3 = calloc(1, sizeof(Edje_Message_Signal));
392 if (emsg2->sig) emsg3->sig = eina_stringshare_add(emsg2->sig);
393 if (emsg2->src) emsg3->src = eina_stringshare_add(emsg2->src);
394 if (emsg2->data)
395 {
396 emsg3->data = emsg2->data;
397 emsg3->data->ref++;
398 }
399 msg = (unsigned char *)emsg3;
400 }
401 break;
402 case EDJE_MESSAGE_STRING:
403 {
404 Edje_Message_String *emsg2, *emsg3;
405
406 emsg2 = (Edje_Message_String *)emsg;
407
408 emsg3 = malloc(sizeof(Edje_Message_String));
409 emsg3->str = strdup(emsg2->str);
410 msg = (unsigned char *)emsg3;
411 }
412 break;
413 case EDJE_MESSAGE_INT:
414 {
415 Edje_Message_Int *emsg2, *emsg3;
416
417 emsg2 = (Edje_Message_Int *)emsg;
418 emsg3 = malloc(sizeof(Edje_Message_Int));
419 emsg3->val = emsg2->val;
420 msg = (unsigned char *)emsg3;
421 }
422 break;
423 case EDJE_MESSAGE_FLOAT:
424 {
425 Edje_Message_Float *emsg2, *emsg3;
426
427 emsg2 = (Edje_Message_Float *)emsg;
428 emsg3 = malloc(sizeof(Edje_Message_Float));
429 emsg3->val = emsg2->val;
430 msg = (unsigned char *)emsg3;
431 }
432 break;
433 case EDJE_MESSAGE_STRING_SET:
434 {
435 Edje_Message_String_Set *emsg2, *emsg3;
436
437 emsg2 = (Edje_Message_String_Set *)emsg;
438 emsg3 = malloc(sizeof(Edje_Message_String_Set) + ((emsg2->count - 1) * sizeof(char *)));
439 emsg3->count = emsg2->count;
440 for (i = 0; i < emsg3->count; i++)
441 emsg3->str[i] = strdup(emsg2->str[i]);
442 msg = (unsigned char *)emsg3;
443 }
444 break;
445 case EDJE_MESSAGE_INT_SET:
446 {
447 Edje_Message_Int_Set *emsg2, *emsg3;
448
449 emsg2 = (Edje_Message_Int_Set *)emsg;
450 emsg3 = malloc(sizeof(Edje_Message_Int_Set) + ((emsg2->count - 1) * sizeof(int)));
451 emsg3->count = emsg2->count;
452 for (i = 0; i < emsg3->count; i++)
453 emsg3->val[i] = emsg2->val[i];
454 msg = (unsigned char *)emsg3;
455 }
456 break;
457 case EDJE_MESSAGE_FLOAT_SET:
458 {
459 Edje_Message_Float_Set *emsg2, *emsg3;
460
461 emsg2 = (Edje_Message_Float_Set *)emsg;
462 emsg3 = malloc(sizeof(Edje_Message_Float_Set) + ((emsg2->count - 1) * sizeof(double)));
463 emsg3->count = emsg2->count;
464 for (i = 0; i < emsg3->count; i++)
465 emsg3->val[i] = emsg2->val[i];
466 msg = (unsigned char *)emsg3;
467 }
468 break;
469 case EDJE_MESSAGE_STRING_INT:
470 {
471 Edje_Message_String_Int *emsg2, *emsg3;
472
473 emsg2 = (Edje_Message_String_Int *)emsg;
474 emsg3 = malloc(sizeof(Edje_Message_String_Int));
475 emsg3->str = strdup(emsg2->str);
476 emsg3->val = emsg2->val;
477 msg = (unsigned char *)emsg3;
478 }
479 break;
480 case EDJE_MESSAGE_STRING_FLOAT:
481 {
482 Edje_Message_String_Float *emsg2, *emsg3;
483
484 emsg2 = (Edje_Message_String_Float *)emsg;
485 emsg3 = malloc(sizeof(Edje_Message_String_Float));
486 emsg3->str = strdup(emsg2->str);
487 emsg3->val = emsg2->val;
488 msg = (unsigned char *)emsg3;
489 }
490 break;
491 case EDJE_MESSAGE_STRING_INT_SET:
492 {
493 Edje_Message_String_Int_Set *emsg2, *emsg3;
494
495 emsg2 = (Edje_Message_String_Int_Set *)emsg;
496 emsg3 = malloc(sizeof(Edje_Message_String_Int_Set) + ((emsg2->count - 1) * sizeof(int)));
497 emsg3->str = strdup(emsg2->str);
498 emsg3->count = emsg2->count;
499 for (i = 0; i < emsg3->count; i++)
500 emsg3->val[i] = emsg2->val[i];
501 msg = (unsigned char *)emsg3;
502 }
503 break;
504 case EDJE_MESSAGE_STRING_FLOAT_SET:
505 {
506 Edje_Message_String_Float_Set *emsg2, *emsg3;
507
508 emsg2 = (Edje_Message_String_Float_Set *)emsg;
509 emsg3 = malloc(sizeof(Edje_Message_String_Float_Set) + ((emsg2->count - 1) * sizeof(double)));
510 emsg3->str = strdup(emsg2->str);
511 emsg3->count = emsg2->count;
512 for (i = 0; i < emsg3->count; i++)
513 emsg3->val[i] = emsg2->val[i];
514 msg = (unsigned char *)emsg3;
515 }
516 break;
517 default:
518 break;
519 }
520
521 em->msg = msg;
522 msgq = eina_list_append(msgq, em);
523}
524
525void
526_edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg)
527{
528 _edje_message_propornot_send(ed, queue, type, id, emsg, EINA_FALSE);
529}
530
531void
532_edje_message_parameters_push(Edje_Message *em)
533{
534 int i;
535
536 /* these params ALWAYS go on */
537 /* first param is the message type - always */
538 embryo_parameter_cell_push(em->edje->collection->script,
539 (Embryo_Cell)em->type);
540 /* 2nd param is the integer of the event id - always there */
541 embryo_parameter_cell_push(em->edje->collection->script,
542 (Embryo_Cell)em->id);
543 /* the rest is varags of whatever is in the msg */
544 switch (em->type)
545 {
546 case EDJE_MESSAGE_NONE:
547 break;
548 case EDJE_MESSAGE_STRING:
549 embryo_parameter_string_push(em->edje->collection->script,
550 ((Edje_Message_String *)em->msg)->str);
551 break;
552 case EDJE_MESSAGE_INT:
553 {
554 Embryo_Cell v;
555
556 v = (Embryo_Cell)((Edje_Message_Int *)em->msg)->val;
557 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
558 }
559 break;
560 case EDJE_MESSAGE_FLOAT:
561 {
562 Embryo_Cell v;
563 float fv;
564
565 fv = ((Edje_Message_Float *)em->msg)->val;
566 v = EMBRYO_FLOAT_TO_CELL(fv);
567 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
568 }
569 break;
570 case EDJE_MESSAGE_STRING_SET:
571 for (i = 0; i < ((Edje_Message_String_Set *)em->msg)->count; i++)
572 embryo_parameter_string_push(em->edje->collection->script,
573 ((Edje_Message_String_Set *)em->msg)->str[i]);
574 break;
575 case EDJE_MESSAGE_INT_SET:
576 for (i = 0; i < ((Edje_Message_Int_Set *)em->msg)->count; i++)
577 {
578 Embryo_Cell v;
579
580 v = (Embryo_Cell)((Edje_Message_Int_Set *)em->msg)->val[i];
581 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
582 }
583 break;
584 case EDJE_MESSAGE_FLOAT_SET:
585 for (i = 0; i < ((Edje_Message_Float_Set *)em->msg)->count; i++)
586 {
587 Embryo_Cell v;
588 float fv;
589
590 fv = ((Edje_Message_Float_Set *)em->msg)->val[i];
591 v = EMBRYO_FLOAT_TO_CELL(fv);
592 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
593 }
594 break;
595 case EDJE_MESSAGE_STRING_INT:
596 embryo_parameter_string_push(em->edje->collection->script,
597 ((Edje_Message_String_Int *)em->msg)->str);
598 {
599 Embryo_Cell v;
600
601 v = (Embryo_Cell)((Edje_Message_String_Int *)em->msg)->val;
602 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
603 }
604 break;
605 case EDJE_MESSAGE_STRING_FLOAT:
606 embryo_parameter_string_push(em->edje->collection->script,
607 ((Edje_Message_String_Float *)em->msg)->str);
608 {
609 Embryo_Cell v;
610 float fv;
611
612 fv = ((Edje_Message_String_Float *)em->msg)->val;
613 v = EMBRYO_FLOAT_TO_CELL(fv);
614 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
615 }
616 break;
617 case EDJE_MESSAGE_STRING_INT_SET:
618 embryo_parameter_string_push(em->edje->collection->script,
619 ((Edje_Message_String_Int_Set *)em->msg)->str);
620 for (i = 0; i < ((Edje_Message_String_Int_Set *)em->msg)->count; i++)
621 {
622 Embryo_Cell v;
623
624 v = (Embryo_Cell)((Edje_Message_String_Int_Set *)em->msg)->val[i];
625 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
626 }
627 break;
628 case EDJE_MESSAGE_STRING_FLOAT_SET:
629 embryo_parameter_string_push(em->edje->collection->script,
630 ((Edje_Message_String_Float_Set *)em->msg)->str);
631 for (i = 0; i < ((Edje_Message_String_Float_Set *)em->msg)->count; i++)
632 {
633 Embryo_Cell v;
634 float fv;
635
636 fv = ((Edje_Message_String_Float_Set *)em->msg)->val[i];
637 v = EMBRYO_FLOAT_TO_CELL(fv);
638 embryo_parameter_cell_array_push(em->edje->collection->script, &v, 1);
639 }
640 break;
641 default:
642 break;
643 }
644}
645
646void
647_edje_message_process(Edje_Message *em)
648{
649 Embryo_Function fn;
650 void *pdata;
651 int ret;
652
653 /* signals are only handled one way */
654 if (em->type == EDJE_MESSAGE_SIGNAL)
655 {
656 _edje_emit_handle(em->edje,
657 ((Edje_Message_Signal *)em->msg)->sig,
658 ((Edje_Message_Signal *)em->msg)->src,
659 ((Edje_Message_Signal *)em->msg)->data,
660 em->propagated);
661 return;
662 }
663 /* if this has been queued up for the app then just call the callback */
664 if (em->queue == EDJE_QUEUE_APP)
665 {
666 if (em->edje->message.func)
667 em->edje->message.func(em->edje->message.data, em->edje->obj,
668 em->type, em->id, em->msg);
669 return;
670 }
671 /* now this message is destined for the script message handler fn */
672 if (!(em->edje->collection)) return;
673 if ((em->edje->collection->script) && _edje_script_only (em->edje))
674 {
675 _edje_script_only_message(em->edje, em);
676 return;
677 }
678 if (em->edje->L)
679 {
680 _edje_lua_script_only_message(em->edje, em);
681 return;
682 }
683 fn = embryo_program_function_find(em->edje->collection->script, "message");
684 if (fn == EMBRYO_FUNCTION_NONE) return;
685 /* reset the engine */
686 _edje_embryo_script_reset(em->edje);
687
688 _edje_message_parameters_push(em);
689
690 embryo_program_vm_push(em->edje->collection->script);
691 _edje_embryo_globals_init(em->edje);
692 pdata = embryo_program_data_get(em->edje->collection->script);
693 embryo_program_data_set(em->edje->collection->script, em->edje);
694 embryo_program_max_cycle_run_set(em->edje->collection->script, 5000000);
695 ret = embryo_program_run(em->edje->collection->script, fn);
696 if (ret == EMBRYO_PROGRAM_FAIL)
697 {
698 ERR("ERROR with embryo script. "
699 "OBJECT NAME: '%s', "
700 "OBJECT FILE: '%s', "
701 "ENTRY POINT: '%s', "
702 "ERROR: '%s'",
703 em->edje->collection->part,
704 em->edje->file->path,
705 "message",
706 embryo_error_string_get(embryo_program_error_get(em->edje->collection->script)));
707 }
708 else if (ret == EMBRYO_PROGRAM_TOOLONG)
709 {
710 ERR("ERROR with embryo script. "
711 "OBJECT NAME: '%s', "
712 "OBJECT FILE: '%s', "
713 "ENTRY POINT: '%s', "
714 "ERROR: 'Script exceeded maximum allowed cycle count of %i'",
715 em->edje->collection->part,
716 em->edje->file->path,
717 "message",
718 embryo_program_max_cycle_run_get(em->edje->collection->script));
719 }
720
721 embryo_program_data_set(em->edje->collection->script, pdata);
722 embryo_program_vm_pop(em->edje->collection->script);
723}
724
725void
726_edje_message_queue_process(void)
727{
728 int i;
729
730 if (!msgq) return;
731
732 /* allow the message queue to feed itself up to 8 times before forcing */
733 /* us to go back to normal processing and let a 0 timeout deal with it */
734 for (i = 0; (i < 8) && (msgq); i++)
735 {
736 /* a temporary message queue */
737 if (tmp_msgq)
738 {
739 while (msgq)
740 {
741 tmp_msgq = eina_list_append(tmp_msgq, msgq->data);
742 msgq = eina_list_remove_list(msgq, msgq);
743 }
744 }
745 else
746 {
747 tmp_msgq = msgq;
748 msgq = NULL;
749 }
750
751 tmp_msgq_processing++;
752 while (tmp_msgq)
753 {
754 Edje_Message *em;
755 Edje *ed;
756
757 em = tmp_msgq->data;
758 ed = em->edje;
759 tmp_msgq = eina_list_remove_list(tmp_msgq, tmp_msgq);
760 em->edje->message.num--;
761 if (!ed->delete_me)
762 {
763 ed->processing_messages++;
764 _edje_message_process(em);
765 _edje_message_free(em);
766 ed->processing_messages--;
767 }
768 else
769 _edje_message_free(em);
770 if (ed->processing_messages == 0)
771 {
772 if (ed->delete_me) _edje_del(ed);
773 }
774 }
775 tmp_msgq_processing--;
776 if (tmp_msgq_processing == 0)
777 tmp_msgq_restart = 0;
778 else
779 tmp_msgq_restart = 1;
780 }
781
782 /* if the message queue filled again set a timer to expire in 0.0 sec */
783 /* to get the idle enterer to be run again */
784 if (msgq)
785 {
786 static int self_feed_debug = -1;
787
788 if (self_feed_debug == -1)
789 {
790 const char *s = getenv("EDJE_SELF_FEED_DEBUG");
791 if (s) self_feed_debug = atoi(s);
792 else self_feed_debug = 0;
793 }
794 if (self_feed_debug)
795 {
796 WRN("Edje is in a self-feeding message loop (> 8 loops needed)");
797 }
798 ecore_timer_add(0.0, _edje_dummy_timer, NULL);
799 }
800}
801
802void
803_edje_message_queue_clear(void)
804{
805 while (msgq)
806 {
807 Edje_Message *em;
808
809 em = msgq->data;
810 msgq = eina_list_remove_list(msgq, msgq);
811 em->edje->message.num--;
812 _edje_message_free(em);
813 }
814 while (tmp_msgq)
815 {
816 Edje_Message *em;
817
818 em = tmp_msgq->data;
819 tmp_msgq = eina_list_remove_list(tmp_msgq, tmp_msgq);
820 em->edje->message.num--;
821 _edje_message_free(em);
822 }
823}
824
825void
826_edje_message_del(Edje *ed)
827{
828 Eina_List *l;
829
830 if (ed->message.num <= 0) return;
831 /* delete any messages on the main queue for this edje object */
832 for (l = msgq; l; )
833 {
834 Edje_Message *em;
835 Eina_List *lp;
836
837 em = eina_list_data_get(l);
838 lp = l;
839 l = eina_list_next(l);
840 if (em->edje == ed)
841 {
842 msgq = eina_list_remove_list(msgq, lp);
843 em->edje->message.num--;
844 _edje_message_free(em);
845 }
846 if (ed->message.num <= 0) return;
847 }
848 /* delete any on the processing queue */
849 for (l = tmp_msgq; l; )
850 {
851 Edje_Message *em;
852 Eina_List *lp;
853
854 em = eina_list_data_get(l);
855 lp = l;
856 l = eina_list_next(l);
857 if (em->edje == ed)
858 {
859 tmp_msgq = eina_list_remove_list(tmp_msgq, lp);
860 em->edje->message.num--;
861 _edje_message_free(em);
862 }
863 if (ed->message.num <= 0) return;
864 }
865}