Eo: Added support for event freeze/thaw.
authortasn <tasn>
Tue, 15 May 2012 14:17:03 +0000 (14:17 +0000)
committertasn <tasn@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 15 May 2012 14:17:03 +0000 (14:17 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/PROTO/eobj@71120 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

examples/signals/main.c
lib/Eo.h
lib/eo_base_class.c

index 7ceb523..7636fc8 100644 (file)
@@ -67,6 +67,112 @@ main(int argc, char *argv[])
    fail_if(ret);
    fail_if(pd->cb_count != 0);
 
+
+   /* Freeze/thaw. */
+   int fcount = 0;
+   cb_count = 0;
+   eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+   fail_if(pd->cb_count != 1);
+
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_do(obj, eo_event_freeze());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 1);
+
+   eo_do(obj, eo_event_freeze());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 2);
+
+   eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+   fail_if(pd->cb_count != 1);
+
+   eo_do(obj, simple_a_set(2));
+   fail_if(cb_count != 0);
+   eo_do(obj, eo_event_thaw());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 1);
+
+   eo_do(obj, eo_event_thaw());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_do(obj, simple_a_set(3));
+   fail_if(cb_count != 2);
+
+   cb_count = 0;
+   eo_do(obj, eo_event_thaw());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_do(obj, eo_event_freeze());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 1);
+
+   eo_do(obj, simple_a_set(2));
+   fail_if(cb_count != 0);
+   eo_do(obj, eo_event_thaw());
+   eo_do(obj, eo_event_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret));
+   fail_if(!ret);
+   eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret));
+   fail_if(!ret);
+   eo_do(obj, eo_event_callback_del_lazy(EV_A_CHANGED, _a_changed_cb, &ret));
+   fail_if(ret);
+
+   /* Global Freeze/thaw. */
+   fcount = 0;
+   cb_count = 0;
+   pd->cb_count = 0;
+   eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 1));
+   fail_if(pd->cb_count != 1);
+
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 1);
+
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 2);
+
+   eo_do(obj, eo_event_callback_priority_add(EV_A_CHANGED, EO_CALLBACK_PRIORITY_BEFORE, _a_changed_cb, (void *) 2));
+   fail_if(pd->cb_count != 1);
+
+   eo_do(obj, simple_a_set(2));
+   fail_if(cb_count != 0);
+   eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 1);
+
+   eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_do(obj, simple_a_set(3));
+   fail_if(cb_count != 2);
+
+   cb_count = 0;
+   eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 1);
+
+   eo_do(obj, simple_a_set(2));
+   fail_if(cb_count != 0);
+   eo_class_do(EO_BASE_CLASS, eo_event_global_thaw());
+   eo_class_do(EO_BASE_CLASS, eo_event_global_freeze_get(&fcount));
+   fail_if(fcount != 0);
+
+
    eo_unref(obj);
    eo_shutdown();
    return 0;
index 1e41674..36ca914 100644 (file)
--- a/lib/Eo.h
+++ b/lib/Eo.h
@@ -791,6 +791,12 @@ enum {
      EO_BASE_SUB_ID_EVENT_CALLBACK_CALL,
      EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD,
      EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL,
+     EO_BASE_SUB_ID_EVENT_FREEZE,
+     EO_BASE_SUB_ID_EVENT_THAW,
+     EO_BASE_SUB_ID_EVENT_FREEZE_GET,
+     EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE,
+     EO_BASE_SUB_ID_EVENT_GLOBAL_THAW,
+     EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET,
      EO_BASE_SUB_ID_LAST
 };
 
@@ -953,6 +959,75 @@ typedef Eina_Bool (*Eo_Event_Cb)(void *data, Eo *obj, const Eo_Event_Description
 #define eo_event_callback_forwarder_del(desc, new_obj) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), EO_TYPECHECK(const Eo_Event_Description *, desc), EO_TYPECHECK(Eo *, new_obj)
 
 /**
+ * @def eo_event_freeze
+ * @brief freeze events of object.
+ *
+ * Prevents event callbacks from being called for the object.
+ *
+ * @see #eo_event_thaw
+ */
+#define eo_event_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE)
+
+/**
+ * @def eo_event_thaw
+ * @brief thaw events of object.
+ *
+ * Lets event callbacks be called for the object.
+ *
+ * @see #eo_event_freeze
+ */
+#define eo_event_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW)
+
+/**
+ * @def eo_event_freeze_get
+ * @brief return freeze events of object.
+ *
+ * @param fcount[out] The event freeze count of the object.
+ *
+ * Return event freeze count.
+ *
+ * @see #eo_event_freeze
+ * @see #eo_event_thaw
+ */
+#define eo_event_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), EO_TYPECHECK(int *, fcount)
+
+/**
+ * @def eo_event_global_freeze
+ * @brief freeze events of object.
+ *
+ * Prevents event callbacks from being called for the object.
+ *
+ * @see #eo_event_freeze
+ * @see #eo_event_global_thaw
+ */
+#define eo_event_global_freeze() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE)
+
+/**
+ * @def eo_event_global_thaw
+ * @brief thaw events of object.
+ *
+ * Lets event callbacks be called for the object.
+ *
+ * @see #eo_event_thaw
+ * @see #eo_event_global_freeze
+ */
+#define eo_event_global_thaw() EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW)
+
+/**
+ * @def eo_event_global_freeze_get
+ * @brief return freeze events of object.
+ *
+ * @param fcount[out] The event freeze count of the object.
+ *
+ * Return event freeze count.
+ *
+ * @see #eo_event_freeze_get
+ * @see #eo_event_global_freeze
+ * @see #eo_event_global_thaw
+ */
+#define eo_event_global_freeze_get(fcount) EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET), EO_TYPECHECK(int *, fcount)
+
+/**
  * @def eo_event_callback_add(obj, desc, cb, data)
  * Add a callback for an event.
  * @param desc[in] The description of the event to listen to.
index c0e24d6..5de6b3a 100644 (file)
@@ -7,6 +7,8 @@
 
 EAPI Eo_Op EO_BASE_BASE_ID = EO_NOOP;
 
+static int event_freeze_count = 0;
+
 typedef struct
 {
    Eina_Inlist *generic_data;
@@ -14,6 +16,7 @@ typedef struct
 
    Eina_Inlist *callbacks;
    int walking_list;
+   int event_freeze_count;
 } Private_Data;
 
 typedef struct
@@ -373,6 +376,9 @@ _ev_cb_call(const Eo *_obj, const void *class_data, va_list *list)
 
    if (ret) *ret = EINA_TRUE;
 
+   if (event_freeze_count || pd->event_freeze_count)
+      return;
+
    /* FIXME: Change eo_ref to _eo_ref and unref. */
    eo_ref(obj);
    pd->walking_list++;
@@ -426,6 +432,62 @@ _ev_cb_forwarder_del(Eo *obj, void *class_data EINA_UNUSED, va_list *list)
    eo_do(obj, eo_event_callback_del(desc, _eo_event_forwarder_callback, new_obj));
 }
 
+static void
+_ev_freeze(Eo *obj EINA_UNUSED, void *class_data, va_list *list EINA_UNUSED)
+{
+   Private_Data *pd = (Private_Data *) class_data;
+   pd->event_freeze_count++;
+}
+
+static void
+_ev_thaw(Eo *obj, void *class_data, va_list *list EINA_UNUSED)
+{
+   Private_Data *pd = (Private_Data *) class_data;
+   if (pd->event_freeze_count > 0)
+     {
+        pd->event_freeze_count--;
+     }
+   else
+     {
+        ERR("Events for object %p have already been thawed.", obj);
+     }
+}
+
+static void
+_ev_freeze_get(const Eo *obj EINA_UNUSED, const void *class_data, va_list *list)
+{
+   Private_Data *pd = (Private_Data *) class_data;
+   int *ret = va_arg(*list, int *);
+   *ret = pd->event_freeze_count;
+}
+
+static void
+_ev_global_freeze(const Eo_Class *klass EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+   event_freeze_count++;
+}
+
+static void
+_ev_global_thaw(const Eo_Class *klass EINA_UNUSED, va_list *list EINA_UNUSED)
+{
+   if (event_freeze_count > 0)
+     {
+        event_freeze_count--;
+     }
+   else
+     {
+        ERR("Global events have already been thawed.");
+     }
+}
+
+static void
+_ev_global_freeze_get(const Eo_Class *klass EINA_UNUSED, va_list *list)
+{
+   int *ret = va_arg(*list, int *);
+   *ret = event_freeze_count;
+}
+
+
 /* EOF event callbacks */
 
 
@@ -459,6 +521,8 @@ _destructor(Eo *obj, void *class_data)
 static void
 _class_constructor(Eo_Class *klass)
 {
+   event_freeze_count = 0;
+
    const Eo_Op_Func_Description func_desc[] = {
         EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_DATA_SET), _data_set),
         EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_DATA_GET), _data_get),
@@ -471,6 +535,12 @@ _class_constructor(Eo_Class *klass)
         EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL), _ev_cb_call),
         EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD), _ev_cb_forwarder_add),
         EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL), _ev_cb_forwarder_del),
+        EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE), _ev_freeze),
+        EO_OP_FUNC(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_THAW), _ev_thaw),
+        EO_OP_FUNC_CONST(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_FREEZE_GET), _ev_freeze_get),
+        EO_OP_FUNC_CLASS(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE), _ev_global_freeze),
+        EO_OP_FUNC_CLASS(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW), _ev_global_thaw),
+        EO_OP_FUNC_CLASS(EO_BASE_ID(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET), _ev_global_freeze_get),
         EO_OP_FUNC_SENTINEL
    };
 
@@ -489,6 +559,12 @@ static const Eo_Op_Description op_desc[] = {
      EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_EVENT_CALLBACK_CALL, "?", "Call the event callbacks for an event."),
      EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_ADD, "?", "Add an event forwarder."),
      EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_CALLBACK_FORWARDER_DEL, "?", "Delete an event forwarder."),
+     EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_FREEZE, "?", "Freezes events."),
+     EO_OP_DESCRIPTION(EO_BASE_SUB_ID_EVENT_THAW, "?", "Thaws events."),
+     EO_OP_DESCRIPTION_CONST(EO_BASE_SUB_ID_EVENT_FREEZE_GET, "?", "Get event freeze counter."),
+     EO_OP_DESCRIPTION_CLASS(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE, "?", "Freezes events globally."),
+     EO_OP_DESCRIPTION_CLASS(EO_BASE_SUB_ID_EVENT_GLOBAL_THAW, "?", "Thaws events globally."),
+     EO_OP_DESCRIPTION_CLASS(EO_BASE_SUB_ID_EVENT_GLOBAL_FREEZE_GET, "?", "Get global event freeze counter."),
      EO_OP_DESCRIPTION_SENTINEL
 };